Skip to content

Commit 614d6ae

Browse files
committed
Add semaphore to enforce one-at-a-time message processing
- Add semaphore to Proc struct for concurrent access control - Remove semaphore from Endpoint struct (moved to Proc) - Add semaphore acquisition/release in ProcessMessage for async mode - Ensures messages are processed sequentially to maintain order - Add IPFS field to ProcConfig for filesystem mounting - Add NewFSConfig method to mount IPFS filesystem at /ipfs, /ipns, /ipld paths
1 parent 1212f6d commit 614d6ae

2 files changed

Lines changed: 27 additions & 10 deletions

File tree

system/proc.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
)
2222

2323
type ProcConfig struct {
24+
IPFS IPFS
2425
Host host.Host
2526
Runtime wazero.Runtime
2627
Src io.ReadCloser
@@ -76,7 +77,7 @@ func (c ProcConfig) New(ctx context.Context) (*Proc, error) {
7677
}
7778

7879
// Configure module instantiation based on async mode
79-
config := c.NewModuleConfig(e)
80+
config := c.NewModuleConfig(ctx, e)
8081

8182
mod, err := c.Runtime.InstantiateModule(ctx, cm, config)
8283
if err != nil {
@@ -107,7 +108,8 @@ func (c ProcConfig) New(ctx context.Context) (*Proc, error) {
107108
Config: c,
108109
Module: mod,
109110
Endpoint: e,
110-
Closer: cs}
111+
Closer: cs,
112+
sem: semaphore.NewWeighted(1)}
111113
return proc, nil
112114
}
113115

@@ -116,13 +118,14 @@ type ReadWriteStringer interface {
116118
io.ReadWriter
117119
}
118120

119-
func (c ProcConfig) NewModuleConfig(sock ReadWriteStringer) wazero.ModuleConfig {
121+
func (c ProcConfig) NewModuleConfig(ctx context.Context, sock ReadWriteStringer) wazero.ModuleConfig {
120122
config := wazero.NewModuleConfig().
121123
WithName(sock.String()).
122124
WithArgs(c.Args...).
123125
WithStdin(sock).
124126
WithStdout(sock).
125-
WithStderr(c.ErrWriter)
127+
WithStderr(c.ErrWriter).
128+
WithFSConfig(c.NewFSConfig(ctx))
126129

127130
// async mode?
128131
if c.Async {
@@ -140,23 +143,34 @@ func (c ProcConfig) NewModuleConfig(sock ReadWriteStringer) wazero.ModuleConfig
140143
return config
141144
}
142145

146+
func (c ProcConfig) NewFSConfig(ctx context.Context) wazero.FSConfig {
147+
ipfs := IPFS{
148+
Ctx: ctx,
149+
Unix: c.IPFS.Unix,
150+
Root: c.IPFS.Root}
151+
152+
return wazero.NewFSConfig().
153+
WithFSMount(ipfs, "/ipfs").
154+
WithFSMount(ipfs, "/ipns").
155+
WithFSMount(ipfs, "/ipld")
156+
}
157+
143158
func (p ProcConfig) NewEndpoint() *Endpoint {
144159
var buf [8]byte
145160
if _, err := io.ReadFull(rand.Reader, buf[:]); err != nil {
146161
panic(err)
147162
}
148163

149-
return &Endpoint{
150-
Name: base58.FastBase58Encoding(buf[:]),
151-
sem: semaphore.NewWeighted(1),
152-
}
164+
return &Endpoint{Name: base58.FastBase58Encoding(buf[:])}
153165
}
154166

155167
type Proc struct {
156168
Config ProcConfig
157169
Endpoint *Endpoint
158170
Module api.Module
159171
api.Closer
172+
173+
sem *semaphore.Weighted
160174
}
161175

162176
// ID returns the process identifier (endpoint name) without the protocol prefix.
@@ -200,6 +214,11 @@ func (p Proc) ProcessMessage(ctx context.Context, s network.Stream, method strin
200214
return fmt.Errorf("unknown method: %s", method)
201215
}
202216

217+
if err := p.sem.Acquire(ctx, 1); err != nil {
218+
return fmt.Errorf("acquire semaphore: %w", err)
219+
}
220+
defer p.sem.Release(1)
221+
203222
if err := exp.CallWithStack(ctx, nil); err != nil {
204223
var exitErr *sys.ExitError
205224
if errors.As(err, &exitErr) && exitErr.ExitCode() != 0 {

system/system.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ import (
55
"io"
66

77
"github.com/libp2p/go-libp2p/core/protocol"
8-
"golang.org/x/sync/semaphore"
98
)
109

1110
type Endpoint struct {
1211
Name string
1312
io.ReadWriteCloser
14-
sem *semaphore.Weighted
1513
}
1614

1715
// Read implements io.Reader for Endpoint

0 commit comments

Comments
 (0)