karlkfi / inject

Dependency injection library for Go (golang)
Apache License 2.0
80 stars 7 forks source link

Order of the Finalizable process #6

Open basilex opened 7 years ago

basilex commented 7 years ago

Hi, Karl!

The question regarding the order (which in may case is very important) during executing Finalize funcs at the end of an app. So, the code:

package main

import (
    "flag"
    "log"

    "github.com/karlkfi/inject"
)

var (
    ctx        CtxInterface
    indicator  IndicatorInterface
    translator TranslatorInterface

    config = flag.String("config-file", "./etc/banjo-dev.toml", "Banjo configuration file")
)

func main() {
    flag.Parse()

    graph := inject.NewGraph()

    graph.Define(&ctx, inject.NewProvider(NewCtx, config))
    graph.Define(&indicator, inject.NewProvider(NewIndicator, &ctx))
    graph.Define(&translator, inject.NewProvider(NewTranslator, &ctx))
    graph.ResolveAll()

    log.Printf("banjo: indicator: %T, %v", indicator, indicator)
    log.Printf("banjo: translator: %T, %v", translator, translator)

    indicator.Display(translator.T("test1"))
    graph.Finalize()
}

Above snippet of code initializes and executes successfully, but at the end of the application inject calls Finalizable funcs in random order...

First run:

> $ ./bin/banjo-linux-amd64
2017/01/10 11:07:49 banjo: initializing instance ctx...
2017/01/10 11:07:49 banjo: initializing instance indicator...
2017/01/10 11:07:49 banjo: initializing instance translator...
2017/01/10 11:07:49 banjo: indicator: *main.Indicator, &{0xc42000e340}
2017/01/10 11:07:49 banjo: translator: *main.Translator, &{0xc42000e340}
2017/01/10 11:07:49 banjo: instance indicator displaying test1: value
2017/01/10 11:07:49 banjo: finalizing instance indicator...
2017/01/10 11:07:49 banjo: finalizing instance translator...
2017/01/10 11:07:49 banjo: finalizing instance ctx...

Next run:

> $ ./bin/banjo-linux-amd64                                                                                                                    [±master ●●]
2017/01/10 11:07:53 banjo: initializing instance ctx...
2017/01/10 11:07:53 banjo: initializing instance indicator...
2017/01/10 11:07:53 banjo: initializing instance translator...
2017/01/10 11:07:53 banjo: indicator: *main.Indicator, &{0xc42000e340}
2017/01/10 11:07:53 banjo: translator: *main.Translator, &{0xc42000e340}
2017/01/10 11:07:53 banjo: instance indicator displaying test1: value
2017/01/10 11:07:53 banjo: finalizing instance ctx...
2017/01/10 11:07:53 banjo: finalizing instance indicator...
2017/01/10 11:07:53 banjo: finalizing instance translator...

So, do you have some suggestions or recommendations? Thanks!

karlkfi commented 7 years ago

Why is it important to you what order they get finalized?

basilex commented 7 years ago

Easy. Db connection for ex, which should be closed at the end, Indicator (specific device for translated messages) for ex should be closed before translator service and so on... (Imagine "GOOD BYE" for display for ukrainian when translation service already closed...) Probably graph of the Fanalizable services should be sorted in reverse order? Thanks!

karlkfi commented 7 years ago

So your Finalize object functions exec code that depends on the object's dependencies?

I guess that's legitimate.

The map being iterated isn't sorted tho. So it can't just iterate in reverse. It would probably have to keep another array around with the dependency order or capture reverse dependence and walk the tree.

Would you like to make a PR?