Skip to content

[👷] Road to v2 🚀 #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 169 commits into
base: master
Choose a base branch
from
Open

[👷] Road to v2 🚀 #45

wants to merge 169 commits into from

Conversation

samber
Copy link
Owner

@samber samber commented Oct 23, 2023

Hi there 👋,

Over the past 18 months, many of you reported bugs or provided valuable feedback on various aspects of this project, such as error handling, debugging, invocation API, documentation, and more... Thanks for your contributions! 🙌

Work on this library has provided me with significant learning opportunities and now I believe it's time to advance this project further.

Most of the work for v2 has been done already. I'm targeting the end of 2023, 2024, 2025 for a release. It will depend on additional requirements.

go get -u github.com/samber/do/v2@v2.0.0-beta.7

Scope

This milestone will lead to major improvement: Scope.

A Scope was previously referred to as an Injector and can be viewed as a module of an application, with restricted visibility. I advocate for each project possessing a RootScope for common code, and shifting business logic to dedicated Scopes.

The Scopes are structured with a parent (RootScope or other Scope), numerous Services, and potentially a few children Scopes as well.

RootScope owns options and is the only Scope that supports cloning.

Services from a Scope can invoke Services available locally or in parent Scopes. Therefore, a single Service can be instantiated many times in different branches of the Scope tree, without conflict.

Scope will be almost invisible to developers: services will keep using Injector API without awareness of the underlying implementation, whether it's a RootScope, Scope or VirtualScope.

A chain of Service invocation will instantiate many VirtualScope, in order to track dependency cycles.

A debugging toolchain has been added to illustrate the service dependency chain and Scope tree.

Checklist

The library has been almost entirely recoded, but most of do@v1 API has been preserved (see breaking changes below).

To be challenged

More existing issues might be added to the v2 milestone.

Documentation

Testing

Code coverage has been improved compared to v1. 😍

  • Reach 80% code coverage
  • Reach 85% code coverage
  • Reach 90% code coverage
  • See // @TODO in xxx_test.go files
  • More tests on nested scopes (clone, service invocation...)
  • More tests on virtual scopes

Coverage:

  • 2023-10-23: 83%
  • 2023-12-30: 87%
  • 2024-05-07: 89%
  • 2025-08-21: 93%

Breaking changes

  • Injector struct turned into an interface 😕
  • ListProvidedServices and ListInvokedServices now return 2 do.Edge arrays.
  • No more panic propagation on Provider error 😛
  • Service implicit names have been changed. BTW, you should never manipulate it! Eg: *mypkg.MyService -> *github.com/samber/example.MyService.
  • injector.ShutdownOnSignals and injector.ShutdownOnSIGTERM now return (os.Signal, error)

If you consider the API must be improved, please write a comment on this issue. No breaking change will be done in v2 minor releases. And I hope v2 is going to be the last major version.

Repository owner deleted a comment from codecov-commenter Oct 23, 2023
@samber
Copy link
Owner Author

samber commented Oct 23, 2023

Debugging

Here is the output of do.ExplainService[*MyService](Injector) 👇

Scope ID: scope-id-123
Scope name: scope-child
Service: SERVICE-E
Service type: lazy
Service build time: 1s
Invoked: /home/samber/project/github.com/samber/do/di_explain_test.go:fakeProvider5:38

Dependencies:
* SERVICE-D from scope scope-child
  * SERVICE-C1 from scope scope-child
    * SERVICE-B from scope [root]
      * SERVICE-A1 from scope [root]
      * SERVICE-A2 from scope [root]
  * SERVICE-C2 from scope scope-child
    * SERVICE-B from scope [root]
      * SERVICE-A1 from scope [root]
      * SERVICE-A2 from scope [root]

Dependents:
* SERVICE-F from scope scope-child
  * SERVICE-G from scope scope-child

Here is the output of do.ExplainInjector(Injector) 👇

Scope ID: scope-id-root
Scope name: [root]

DAG:

\_ [root] (ID: scope-id-root)
    * 😴 SERVICE-A1
    * 😴 SERVICE-A2
    * 😴 SERVICE-B
    |
    |
     \_ scope-0 (ID: scope-id-0)
         |
         |
         |\_ scope-1a (ID: scope-id-1a)
         |    * 😴 SERVICE-C1
         |    * 😴 SERVICE-C2
         |    * 😴 SERVICE-D
         |    * 😴 SERVICE-E
         |    * 🔁 SERVICE-EAGER-VALUE
         |    |
         |    |
         |    |\_ scope-2a (ID: scope-id-2a)
         |    |    * 😴 SERVICE-LAZY-HEALTH 🏥
         |    |    * 🏭 SERVICE-TRANSIANT-SIMPLE
         |    |     
         |    |
         |     \_ scope-2b (ID: scope-id-2b)
         |         * 😴 SERVICE-LAZY-SHUTDOWN 🙅
         |          
         |
          \_ scope-1b (ID: scope-id-1b)
              * 😴 SERVICE-F

The emoji prefix indicates the service is either Lazy, Eager, or Transiant. The EOL emoji indicates the service implements do.HealthChecker and/or do.Shutdowner.

@codecov-commenter
Copy link

codecov-commenter commented Oct 23, 2023

Codecov Report

❌ Patch coverage is 94.67061% with 72 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.14%. Comparing base (ef4a44f) to head (4d53e67).

Files with missing lines Patch % Lines
root_scope.go 83.44% 24 Missing and 1 partial ⚠️
http/service.go 89.72% 14 Missing and 5 partials ⚠️
invoke.go 96.26% 6 Missing and 3 partials ⚠️
http/scope.go 95.55% 4 Missing and 2 partials ⚠️
di_explain.go 98.50% 3 Missing and 1 partial ⚠️
dag.go 95.23% 2 Missing and 1 partial ⚠️
errors.go 92.10% 2 Missing and 1 partial ⚠️
http/utils.go 91.17% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #45      +/-   ##
==========================================
+ Coverage   88.91%   93.14%   +4.23%     
==========================================
  Files           6       22      +16     
  Lines         433     2554    +2121     
==========================================
+ Hits          385     2379    +1994     
- Misses         40      140     +100     
- Partials        8       35      +27     
Flag Coverage Δ
unittests 93.14% <94.67%> (+4.23%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@GreyXor
Copy link
Contributor

GreyXor commented Oct 25, 2023

Hello, that's a really great news! Thanks a lot.
I can't use the branch directly atm

go get github.com/samber/do@v2-🚀
go: github.com/samber/do@v2-🚀: invalid version: version "v2-🚀" invalid: disallowed version string

workaround:
go get github.com/samber/do@d722cd623c629ebfaf5b2032f998d3ae1b176009

@danilobuerger
Copy link

It would be nice to provide context o healthcheck and shutdown.

@samber
Copy link
Owner Author

samber commented Oct 26, 2023

@danilobuerger can you elaborate on your use case?

@danilobuerger
Copy link

@danilobuerger can you elaborate on your use case?

Sure, I want to provide a context to be able to use cancellation.

@GreyXor
Copy link
Contributor

GreyXor commented Nov 1, 2023

My last workaround don't work anymore. I've followed this guide https://github.com/samber/do/blob/v2-%F0%9F%9A%80/MIGRATION-V1-TO-V2.md and also the v2 readme : https://github.com/samber/do/blob/v2-%F0%9F%9A%80/README.md
But I get this error go: github.com/samber/do@v2: no matching versions for query "v2" when I run go get github.com/samber/do@v2

@samber
Copy link
Owner Author

samber commented Nov 1, 2023

I renamed the package samber/do to samber/do/v2, so the latest command is: go get github.com/samber/do/v2@a158d2d9f84b4a1973db49e959e476aca996e04a

Adding an emoji in the branch name was definitely a bad idea 😆

@GreyXor
Copy link
Contributor

GreyXor commented Nov 2, 2023

I renamed the package samber/do to samber/do/v2, so the latest command is: go get github.com/samber/do/v2@a158d2d9f84b4a1973db49e959e476aca996e04a

Adding an emoji in the branch name was definitely a bad idea 😆

Not your fault, go get should be UTF-8 ready imho.

@GreyXor
Copy link
Contributor

GreyXor commented Nov 2, 2023

@samber, Since I've designed the ShutdownOnSignals* function to accommodate any signals, we've maintained the *OnSIGTERM for compatibility purposes. However, now that we have the option to revise the API (by breaking it), I believe all the shutdownOnSIGTERMs are unnecessary.

I therefore propose deleting ShutdownOnSIGTERM, ShutdownOnSIGTERMWithContext, ShutdownOnSIGTERMOrInterrupt and ShutdownOnSIGTERMOrInterruptWithContext.

What do you think about ? I feel that they are redundant

@danilobuerger
Copy link

One thing I noticed is that the pattern of Accept interfaces, return structs doesnt seem possible:

type EngineService interface{}

func NewEngineService(i *do.Injector) (*engineServiceImplem, error) {
    return &engineServiceImplem{}, nil
}

type engineServiceImplem struct {}

Later this fails:

do.Provide[EngineService](injector, NewEngineService)

@samber
Copy link
Owner Author

samber commented Nov 28, 2023

@danilobuerger v2 will make it possible to respect this pattern:

do.As[*engineServiceImplem, EngineService](injector)
// or
do.InvokeAs[EngineService](injector)

See the function comments for the full explanation.

@samber
Copy link
Owner Author

samber commented Aug 22, 2025

Dear do community,

I owe you a sincere apology for the long delay in delivering this second major release. Over the past two years, my professional life has been complicated, and I wasn’t able to give do the attention it deserved. I know many of you have been waiting, and I am truly sorry for keeping you waiting this long.

The good news is: during the last week I was finally able to dedicate daily focus to the project, and we’ve reached some exciting milestones:

  • Fixed long-standing bugs and stabilized previously unstable features
  • Major improvements to the documentation
  • Achieved over 90% test coverage

Today, I’m very happy to share the first release candidate: v2.0.0-rc1 🎉
The stable release is planned for early September.

Important notes

  • One planned feature, value groups, has been postponed to v2.1 so we can move forward with v2.0 without further delays.
  • If you believe there are additional breaking changes that should be made, now is the right time to propose them — once v2.0 is finalized, we’ll aim to keep it stable.

👉 Please upgrade to v2.0.0-rc1, test it in your projects, and share feedback. Your contributions and patience mean a lot, and I want v2.0 to reflect the quality this community deserves fully.

Thank you again for sticking with me on this journey. 😘

@GreyXor
Copy link
Contributor

GreyXor commented Aug 22, 2025

Thank you so much for all the effort you’ve put into this. I hope life is a bit easier for you now and that you’re finding some balance. It’s amazing that, even after a challenging couple of years, you’ve returned to give the project the attention it deserves. The community is really lucky to have your dedication. Can’t wait to test v2.0.0-rc1. Updating right now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.