Skip to content

Commit a5283a5

Browse files
Add support for calling a flow function
1 parent fee0cab commit a5283a5

16 files changed

Lines changed: 666 additions & 172 deletions

File tree

pkg/exports.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Context = runtime.Context
1515

1616
func GetVar[T any](c Context, name string) T { return runtime.GetVar[T](c, name) }
1717
func GetError(c Context, name string) *string { return runtime.GetError(c, name) }
18+
func GetReturn[T any](c Context, idx int) T { return runtime.GetReturn[T](c, idx) }
1819

1920
/* -=[ Async Primitives ]=- */
2021

@@ -58,8 +59,9 @@ func Impure(line int, stmt func(Context)) AwaitBlock {
5859
}
5960
func SubProgram(
6061
line int, program string, argsFn func(Context) map[string]any,
62+
ret func(Context, string),
6163
) AwaitBlock {
62-
return runtime.SubProgram(line, program, argsFn)
64+
return runtime.SubProgram(line, program, argsFn, ret)
6365
}
6466
func Program(body Block, source string, name string) ProgramBlock {
6567
return runtime.Program(body, source, name)
@@ -73,6 +75,9 @@ func Send(line int, id func(Context) string, value func(Context) any) AwaitBlock
7375
func Recv[T any](line int, id func(Context) string, ret func(Context, T)) AwaitBlock {
7476
return runtime.Recv[T](line, id, ret)
7577
}
78+
func Join(line int, id func(Context) string, rets []func(Context, Context)) AwaitBlock {
79+
return runtime.Join(line, id, rets)
80+
}
7681
func RecvAny(
7782
line int,
7883
ids []func(Context) string,

pkg/platforms/interface.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ type MutexReleaseEvent struct {
151151
Id string `json:"id"`
152152
}
153153

154+
type JoinEvent struct {
155+
Id string `json:"id"`
156+
}
157+
154158
func (e HttpRequestEvent) Key() string { return e.Url }
155159
func (e HttpListenEvent) Key() string { return e.Url }
156160
func (e TimerEvent) Key() string { return e.Id }
@@ -167,6 +171,7 @@ func (e WaitGroupWaitEvent) Key() string { return e.Id }
167171
func (e MutexCreateEvent) Key() string { return e.Id }
168172
func (e MutexAcquireEvent) Key() string { return e.Id }
169173
func (e MutexReleaseEvent) Key() string { return e.Id }
174+
func (e JoinEvent) Key() string { return e.Id }
170175

171176
type EventNotify interface {
172177
Target() uint
@@ -260,6 +265,13 @@ type MutexReleaseEventNotify struct {
260265
Id string
261266
Err string
262267
}
268+
type JoinEventNotify struct {
269+
Targ uint
270+
Idx uint
271+
Id string
272+
Ctx Context
273+
Err string
274+
}
263275

264276
func (e HttpListenEventNotify) Target() uint { return e.Targ }
265277
func (e TimerEventNotify) Target() uint { return e.Targ }
@@ -275,6 +287,7 @@ func (e WaitGroupWaitEventNotify) Target() uint { return e.Targ }
275287
func (e MutexCreateEventNotify) Target() uint { return e.Targ }
276288
func (e MutexAcquireEventNotify) Target() uint { return e.Targ }
277289
func (e MutexReleaseEventNotify) Target() uint { return e.Targ }
290+
func (e JoinEventNotify) Target() uint { return e.Targ }
278291
func (e HttpListenEventNotify) Index() uint { return e.Idx }
279292
func (e TimerEventNotify) Index() uint { return e.Idx }
280293
func (e CheckpointEventNotify) Index() uint { return e.Idx }
@@ -289,6 +302,7 @@ func (e WaitGroupWaitEventNotify) Index() uint { return e.Idx }
289302
func (e MutexCreateEventNotify) Index() uint { return e.Idx }
290303
func (e MutexAcquireEventNotify) Index() uint { return e.Idx }
291304
func (e MutexReleaseEventNotify) Index() uint { return e.Idx }
305+
func (e JoinEventNotify) Index() uint { return e.Idx }
292306
func (e HttpListenEventNotify) Key() string { return e.Url }
293307
func (e TimerEventNotify) Key() string { return e.Id }
294308
func (e CheckpointEventNotify) Key() string { return e.Id }
@@ -303,6 +317,7 @@ func (e WaitGroupWaitEventNotify) Key() string { return e.Id }
303317
func (e MutexCreateEventNotify) Key() string { return e.Id }
304318
func (e MutexAcquireEventNotify) Key() string { return e.Id }
305319
func (e MutexReleaseEventNotify) Key() string { return e.Id }
320+
func (e JoinEventNotify) Key() string { return e.Id }
306321

307322
type Trace struct {
308323
ID uint `db:"id"`

pkg/platforms/postgres/postgres.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ func (p *Postgres) Listen(
470470
go mutexCreates(p, platformCh, shutdownCtx)
471471
go mutexAcquires(p, platformCh, shutdownCtx)
472472
go mutexReleases(p, platformCh, shutdownCtx)
473+
go joins(p, platformCh, shutdownCtx)
473474
go tracer(p, shutdownCtx)
474475
}
475476

@@ -1782,6 +1783,76 @@ func mutexReleases(
17821783
)
17831784
}
17841785

1786+
func joins(
1787+
p *Postgres,
1788+
platformCh chan platforms.PlatformNotification,
1789+
shutdownCtx context.Context,
1790+
) {
1791+
type joinRow struct {
1792+
isolate
1793+
JoinID string `db:"join_id"`
1794+
ChildCtx []byte `db:"child_context"`
1795+
}
1796+
1797+
pollLoop(
1798+
p, platformCh, shutdownCtx, p.interval,
1799+
1800+
"joins", `
1801+
WITH locked AS (
1802+
UPDATE isolates
1803+
SET lock = $1
1804+
WHERE id IN (
1805+
SELECT id FROM isolates
1806+
WHERE status = 'awaiting'
1807+
AND lock = -1
1808+
AND events @> '[{"type":"JoinEvent"}]'
1809+
FOR UPDATE SKIP LOCKED
1810+
LIMIT $2
1811+
)
1812+
RETURNING id, events, pc, line, tick, program,
1813+
context
1814+
)
1815+
SELECT locked.id, event_match.idx,
1816+
event_match.join_id,
1817+
child.context AS child_context,
1818+
locked.pc, locked.line, locked.tick, locked.program,
1819+
locked.context
1820+
FROM locked,
1821+
LATERAL (
1822+
SELECT (e.idx - 1)::INT AS idx,
1823+
e.elem->>'id' AS join_id
1824+
FROM jsonb_array_elements(locked.events)
1825+
WITH ORDINALITY AS e(elem, idx)
1826+
WHERE e.elem->>'type' = 'JoinEvent'
1827+
ORDER BY e.idx
1828+
LIMIT 1
1829+
) event_match
1830+
JOIN isolates child
1831+
ON child.name = event_match.join_id
1832+
AND child.status = 'done'
1833+
`, func() []any { return []any{p.id, p.limit} },
1834+
1835+
func(row joinRow, m notifyMatch) platforms.EventNotify {
1836+
ctx, err := platforms.DeserCtxJSON(row.ChildCtx)
1837+
if err != nil {
1838+
log.Printf("platform: joins: unable to convert child context: %v", err)
1839+
return nil
1840+
}
1841+
1842+
return platforms.JoinEventNotify{
1843+
Targ: m.target,
1844+
Idx: m.index,
1845+
Id: row.JoinID,
1846+
Ctx: ctx,
1847+
}
1848+
},
1849+
1850+
func(_ joinRow, pgTxn pgx.Tx) error {
1851+
return pgTxn.Commit(context.Background())
1852+
},
1853+
)
1854+
}
1855+
17851856
func makeRequest(
17861857
url string,
17871858
method string,

0 commit comments

Comments
 (0)