Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (l *lifecycle) Wait() error {
var err error
select {
case <-l.ctx.Done():
err = l.ctx.Err()
err = context.Cause(l.ctx)
case err = <-errors.WaitChanel(l.waitGroup):
l.Stop(err)
}
Expand Down Expand Up @@ -129,7 +129,14 @@ func getProviderName(creator interface{}, index int) string {
return reference
}

parts := strings.Split(reference, ".")
splitCount := -1

if strings.HasPrefix(reference, concurrentFuncRefName) {
reference = concurrentFuncRefName
splitCount = 3
}

parts := strings.SplitN(reference, ".", splitCount)

return parts[len(parts)-(1+index)]
}
Expand Down
28 changes: 27 additions & 1 deletion options.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
package vabastegi

import "context"
import (
"context"
"io"
"time"

"github.com/mrsoftware/errors"
)

// ErrApplicationTimeout .
var ErrApplicationTimeout = errors.New("application timeout")

// Options of Vabastegi.
type Options struct {
Expand Down Expand Up @@ -40,3 +49,20 @@ func WithContext(ctx context.Context) Option {
options.Ctx = ctx
}
}

// WithTimeout used if you need to pass timout for application booting.
func WithTimeout(timeout time.Duration) Option {
return func(options *Options) {
// ignoring cancel
ctx, _ := context.WithTimeoutCause(options.Ctx, timeout, ErrApplicationTimeout)

options.Ctx = ctx
}
}

// WithEventLogger register event handlers for logger.
func WithEventLogger(writer io.Writer, level logLevel) Option {
return func(options *Options) {
options.EventHandlers = append(options.EventHandlers, NewEventLogger(writer, level))
}
}
35 changes: 31 additions & 4 deletions vabastegi.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package vabastegi

import (
"context"
"reflect"
"runtime"
"time"

"github.com/mrsoftware/errors"
)

// Provider is a dependency provider for application.
Expand Down Expand Up @@ -51,18 +55,22 @@ func (a *App[T]) Builds(providers ...Provider[T]) (err error) {
defer func() { a.Events.Publish(&OnApplicationShutdownExecuted{Runtime: time.Since(startAt), Err: err}) }()

for _, provider := range providers {
if err = a.Build(a.Lifecycle.GetContext(), provider); err == nil {
continue
if err = a.Build(a.Lifecycle.GetContext(), provider); err != nil {
return err
}

return err
}

return nil
}

// Build use the provider to set a dependency.
func (a *App[T]) Build(ctx context.Context, provider Provider[T]) (err error) {
select {
case <-ctx.Done():
return context.Cause(ctx)
default:
}

startAt := time.Now()

a.Events.Publish(&OnBuildExecuting{
Expand Down Expand Up @@ -92,3 +100,22 @@ func (a *App[ـ]) Log(level logLevel, message string, args ...interface{}) {
func (a *App[_]) Wait() error {
return a.Lifecycle.Wait()
}

var concurrentFuncRefName = runtime.FuncForPC(reflect.ValueOf(Concurrent[any]).Pointer()).Name()

// Concurrent is if you need to run multiple provider concurrently.
func Concurrent[T any](providers ...Provider[T]) Provider[T] {
return func(ctx context.Context, app *App[T]) error {
wg := errors.NewWaitGroup(errors.WaitGroupWithContext(ctx))

for _, provider := range providers {
provider := provider

wg.DoWithContext(ctx, func(ctx context.Context) error {
return app.Builds(provider)
})
}

return wg.Wait()
}
}