-
Notifications
You must be signed in to change notification settings - Fork 41
Closed
Description
Thank you for your efforts to provide a go implementation of DBOS transact!
I request/recommend adopting some idiomatic go best practices for the library before committing to the 1.0 API contract.
- Remove global variables. Having a default client or registry that is global can make sense, similar to
http.DefaultClientin standard library. But everything should be achievable without it. Imagine I will have 5 DBOS instances concurrently and in parallel for my unit tests. - Separate instantiation from side effects.
package main
func main() {
cfg, err := dbos.Config{logger, database url, admin server, etc, application version, executor id}
myapp := dbos.New(cfg)
err := myapp.Launch(context.Context) // connect to database, start background routines
defer myapp.Shutdown(context.Context) // disconnect from database, shut down background go routines, stop the workflow scheduler
}
The dbos object should contain all the state, for example workflowQueueRegistry, workflow scheduler, gob encoder/decoder, logger, and not rely on separate global variables for each of these.
I recommend these resources for learning idiomatic go libraries:
- https://abhinavg.net/2022/12/06/designing-go-libraries/
- https://abhinavg.net/2023/09/27/future-proof-packages/
You can still provide convenient functions that default to a global, if customers want that convenience.
package dbos
func Launch(ctx context.Context, cfg Config) error {
if globalDBOS != nil {
return NewInitializationError("DBOS already initialized")
}
globalDBOS, err = New(cfg)
if err != nil {
return err
}
return globalDBOS.Launch(ctx)
}
func Shutdown(ctx context.Context) error {
if globalDBOS == nil {
return errors.New("Global DBOS instance is nil, cannot destroy")
}
defer func() { globalDBOS = nil }()
return globalDBOS.Shutdown(ctx)
}
Metadata
Metadata
Assignees
Labels
No labels