Skip to content

Commit 7dd5564

Browse files
committed
use goroutine pool to concurrent forgetinode
in #30 forgetinode was changed into inline ServerOps, this may solove memory oom, but the performance of rm op will be very slow, and it will also hang other ops, so i think add a goroutine pool to limit the max num of forgetinode goroutines, but not affect the performance
1 parent 7d791d2 commit 7dd5564

1 file changed

Lines changed: 24 additions & 5 deletions

File tree

fuseutil/file_system.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"github.com/jacobsa/fuse"
2323
"github.com/jacobsa/fuse/fuseops"
24+
"github.com/panjf2000/ants/v2"
2425
)
2526

2627
// An interface with a method for each op type in the fuseops package. This can
@@ -93,6 +94,12 @@ type fileSystemServer struct {
9394
opsInFlight sync.WaitGroup
9495
}
9596

97+
type opCtx struct {
98+
c *fuse.Connection
99+
ctx context.Context
100+
op interface{}
101+
}
102+
96103
func (s *fileSystemServer) ServeOps(c *fuse.Connection) {
97104
// When we are done, we clean up by waiting for all in-flight ops then
98105
// destroying the file system.
@@ -101,6 +108,17 @@ func (s *fileSystemServer) ServeOps(c *fuse.Connection) {
101108
s.fs.Destroy()
102109
}()
103110

111+
// forget inode ops, which may come in a
112+
// flurry from the kernel and we should
113+
// make a pool to limit the number of goroutines
114+
// one goroutine 2KB, 10w goroutine max 200MB
115+
p, _ := ants.NewPoolWithFunc(100000, func(i interface{}) {
116+
op := i.(opCtx)
117+
s.handleOp(op.c, op.ctx, op.op)
118+
})
119+
120+
defer p.Release()
121+
104122
for {
105123
ctx, op, err := c.ReadOp()
106124
if err == io.EOF {
@@ -113,11 +131,12 @@ func (s *fileSystemServer) ServeOps(c *fuse.Connection) {
113131

114132
s.opsInFlight.Add(1)
115133
if _, ok := op.(*fuseops.ForgetInodeOp); ok {
116-
// Special case: call in this goroutine for
117-
// forget inode ops, which may come in a
118-
// flurry from the kernel and are generally
119-
// cheap for the file system to handle
120-
s.handleOp(c, ctx, op)
134+
op := &opCtx{
135+
c: c,
136+
ctx: ctx,
137+
op: op,
138+
}
139+
p.Invoke(op)
121140
} else {
122141
go s.handleOp(c, ctx, op)
123142
}

0 commit comments

Comments
 (0)