MCPcopy Index your code
hub / github.com/dagger/dagger / getOrInit

Method getOrInit

engine/filesync/change_cache.go:38–90  ·  view source on GitHub ↗
(
	ctx context.Context,
	callKey string,
	fn func(context.Context) (*ChangeWithStat, error),
)

Source from the content-addressed store, hash-verified

36}
37
38func (c *changeCache) getOrInit(
39 ctx context.Context,
40 callKey string,
41 fn func(context.Context) (*ChangeWithStat, error),
42) (*cachedChange, error) {
43 if callKey == "" {
44 return nil, fmt.Errorf("cache call key is empty")
45 }
46
47 c.mu.Lock()
48 if c.ongoingCalls == nil {
49 c.ongoingCalls = make(map[string]*cachedChange)
50 }
51 if c.completedCalls == nil {
52 c.completedCalls = make(map[string]*cachedChange)
53 }
54
55 if res, ok := c.completedCalls[callKey]; ok {
56 res.refCount++
57 c.mu.Unlock()
58 return res, nil
59 }
60
61 if res, ok := c.ongoingCalls[callKey]; ok {
62 res.waiters++
63 c.mu.Unlock()
64 return c.wait(ctx, res)
65 }
66
67 callCtx, cancel := context.WithCancelCause(context.WithoutCancel(ctx))
68 res := &cachedChange{
69 cache: c,
70
71 callKey: callKey,
72
73 waitCh: make(chan struct{}),
74 cancel: cancel,
75 waiters: 1,
76 }
77 c.ongoingCalls[callKey] = res
78
79 go func() {
80 defer close(res.waitCh)
81 val, err := fn(callCtx)
82 res.err = err
83 if err == nil {
84 res.val = val
85 }
86 }()
87
88 c.mu.Unlock()
89 return c.wait(ctx, res)
90}
91
92func (c *changeCache) wait(ctx context.Context, res *cachedChange) (*cachedChange, error) {
93 var err error

Callers 11

GetPreviousChangeMethod · 0.80
RemoveAllMethod · 0.80
MkdirMethod · 0.80
SymlinkMethod · 0.80
HardlinkMethod · 0.80
WriteFileMethod · 0.80
TestChangeCacheErrorsFunction · 0.80
TestChangeCacheReleaseFunction · 0.80
TestChangeCacheEmptyKeyFunction · 0.80

Calls 2

waitMethod · 0.95
closeFunction · 0.85

Tested by 5

TestChangeCacheErrorsFunction · 0.64
TestChangeCacheReleaseFunction · 0.64
TestChangeCacheEmptyKeyFunction · 0.64