Skip to content

Commit

Permalink
doc: healthckeck
Browse files Browse the repository at this point in the history
  • Loading branch information
samber committed Dec 4, 2023
1 parent 943411b commit b72e0d5
Show file tree
Hide file tree
Showing 20 changed files with 155 additions and 59 deletions.
52 changes: 26 additions & 26 deletions docs/docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Getting started
title: 🚀 Getting started
description: Let's discover samber/do in less than 5 minutes.
sidebar_position: 1
---
Expand All @@ -10,7 +10,9 @@ Let's discover **samber/do in less than 5 minutes**.

## What you'll need

[Go](https://go.dev/doc/install/) 18 or more.
Compatible with [Go](https://go.dev/doc/install/) 1.18 or more.

This library has no dependencies except the Go std lib.

Import package:

Expand All @@ -32,6 +34,28 @@ injector := do.New()

Services can be declared as a singleton or a factory. In this example, we will create 2 services `Car` and `Engine`, with a simple dependency relation.

```go
func main() {
// create DI container
i := do.New()

// inject both services into DI container
Provide[*Car](i, NewCar)
Provide[*Engine](i, NewEngine)

// invoking car will instantiate Car services and its Engine dependency
car, err := Invoke[*Car](i)
if err != nil {
log.Fatal(err.Error())
}

car.Start() // that's all folk 🤗

// handle ctrl-c and shutdown services
i.ShutdownOnSignals(syscall.SIGTERM, os.Interrupt)
}
```

Engine:

```go
Expand Down Expand Up @@ -73,27 +97,3 @@ func NewCar(i do.Injector) (*Car, error) {
}, nil
}
```

Now, let's start the application:

```go
func main() {
// create DI container
i := do.New()

// inject both services into DI container
Provide[*Car](i, NewCar)
Provide[*Engine](i, NewEngine)

// invoking car will instantiate Car services and its Engine dependency
car, err := Invoke[*Car](i)
if err != nil {
log.Fatal(err.Error())
}

car.Start() // that's all folk 🤗

// handle ctrl-c and shutdown services
i.ShutdownOnSignals(syscall.SIGTERM, os.Interrupt)
}
```
4 changes: 3 additions & 1 deletion docs/docs/glossary.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
id: glossary
title: Glossary
title: 📚 Glossary
description: Dependency injection glossary
sidebar_position: 6
---
Expand All @@ -19,6 +19,8 @@ A design principle where the flow of control is inverted compared to traditional

In Dependency Injection (DI), an injector is a component that creates instances of classes and manages their dependencies. It's also known as the DI container or IoC (Inversion of Control) container.

`do.Injector` is either a `*do.RootScope`, a `*do.Scope` or a `*do.VirtualScope`.

## DI Container

A DI Container is another term for the Injector in Dependency Injection. It's responsible for providing instances of classes and their dependencies.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/scopes/_category_.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"label": "Injectors",
"label": "📦 Injectors",
"position": 3,
"link": {
"type": "generated-index",
Expand Down
24 changes: 13 additions & 11 deletions docs/docs/scopes/clone.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ sidebar_position: 3

# Clone

Clone has the same service registrations as its parent, but it doesn't share the invoked service state.

Cloning an injector can be very useful for test purposes.

```go
Expand All @@ -21,16 +23,16 @@ injector = injector.Clone()
## Clone with options

```go
injector = injector.CloneWithOpts(&do.InjectorOpts{
HookAfterRegistration func(scope *do.Scope, serviceName string) {
// ...
},
HookAfterShutdown func(scope *do.Scope, serviceName string) {
// ...
},

Logf func(format string, args ...any) {
// ...
},
injector := do.New()

Provide[*Car](i, NewCar)
Provide[Engine](i, NewEngine)

// clone
injector = injector.Clone()

// replace Engine by *MockEngine
do.Override[Engine](injector, func (i do.Injector) (Engine, error) {
return &MockEngine{}, nil
})
```
24 changes: 22 additions & 2 deletions docs/docs/scopes/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ description: Injector options
sidebar_position: 2
---

# Injector options
# Injector

## Default container
## Default options

The simplest way to start is to use the default parameters:

Expand All @@ -16,6 +16,22 @@ import "github.com/samber/do/v2"
injector := do.New()
```

## Global container

For a quick start, you may use the default global container. This is highly discouraged in production.

```go
import "github.com/samber/do/v2"

Provide(nil, ...)
Invoke(nil, ...)

// equal to:

Provide(do.DefaultRootScope, ...)
Invoke(do.DefaultRootScope, ...)
```

## Custom options

```go
Expand All @@ -32,5 +48,9 @@ injector := do.NewWithOps(&do.InjectorOpts{
Logf func(format string, args ...any) {
// ...
},

HealthCheckParallelism: 100,
HealthCheckGlobalTimeout: 1 * time.Second,
HealthCheckTimeout: 100 * time.Millisecond,
})
```
2 changes: 2 additions & 0 deletions docs/docs/scopes/scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ A chain of service invocation instantiates many virtual scopes, to track depende

Scopes are almost invisible to developers: services keep using Injector API without awareness of the underlying implementation, whether it's a root scope, scope or virtual scope.

`do.Injector` interface is either a `*do.RootScope`, a `*do.Scope` or a `*do.VirtualScope`.

## New scope

A root scope is created when calling `do.New()`. Multiple layers of child scopes can be added. Each nested scope shares the same root scope.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/service-invocation/_category_.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"label": "Service invocation",
"label": "🪃 Service invocation",
"position": 2,
"link": {
"type": "generated-index",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ This library offers a great API for assembling a large number of modules with lo

Aliases must be Go interfaces. It can be declared explicitly on injection using `do.As()`, or invoked implicitly using `do.InvokeAs()`.

1. **Implicit alias invocation**: `do.InvokeAs()`
2. **Explicit alias injection**: `do.As()`
1. **Implicit alias invocation**:
- provide struct, invoke interface
- `do.InvokeAs()`
2. **Explicit alias injection**:
- provide struct, bind interface, invoke interface
- `do.As()`

## Implicit invocation (prefered)

Expand Down
9 changes: 7 additions & 2 deletions docs/docs/service-invocation/service-invocation.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ In the context of the Go code you're working with, there are several helper func

- `do.MustInvokeNamed[T any](do.Injector, string) T`: This function is a variant of `do.InvokeNamed` that also panics if the service cannot be created.

:::note
🚀 Lazy services are loaded in invocation order.

🐎 Lazy service invocation is protected against concurrent loading.

🧙‍♂️ When multiple [scopes](../scopes/scope.md) are assembled into a big application, the service lookup is recursive from the current nested scope to the root scope.

:::warning

Circular dependencies are not allowed. Services must be invoked in a Directed Acyclic Graph way.

:::

When multiple [scopes](../scopes/scope.md) are assembled into a big application, the service lookup is recursive from the current nested scope to the root scope.

## Example

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/service-lifecycle/_category_.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"label": "Service lifecycle",
"label": "🧑‍⚕️ Service lifecycle",
"position": 4,
"link": {
"type": "generated-index",
Expand Down
50 changes: 49 additions & 1 deletion docs/docs/service-lifecycle/healthchecker.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ sidebar_position: 1

If your service relies on a dependency, you might want to periodically check its state.

When the `injector.HealthCheck()` function is called, the framework triggers `HealthCheck` method of each service implementing a `Healthchecker` interface, in reverse invocation order.
When the `do.HealthCheck[type]()` or the `injector.HealthCheck()` function is called, the framework triggers `HealthCheck` method of each service implementing a `do.Healthchecker` interface, in reverse invocation order.

🕵️ Service health can be checked individually or globally. Requesting a health check on a nested scope will run checks on ancestors.

Lazy services that were not invoked, are not checked.

## Trigger health check

Expand Down Expand Up @@ -62,3 +66,47 @@ Invoke(i, ...)
ctx := context.WithTimeout(10 * time.Second)
i.HealthCheckWithContext(ctx)
```

## Healthcheck options

The root scope can be created with health check parameters, for controlling parallelism or timeouts.

```go
do.InjectorOpts{
// ...

// By default, heath checks will be triggered concurrently.
// HealthCheckParallelism==1 will trigger sequential checks.
HealthCheckParallelism uint

// When many services are checked at the same time.
HealthCheckGlobalTimeout: time.Duration
HealthCheckTimeout: time.Duration
}
```

Example:

```go
type MyPostgresqlConnection struct {
DB *sql.DB
}

func (pg *MyPostgresqlConnection) Healthcheck() error {
return pg.DB.Ping() // <- might be very slow
}

i := do.NewWithOpts(&do.InjectorOpts{
HealthCheckParallelism: 100,
HealthCheckGlobalTimeout: 1 * time.Second,
HealthCheckTimeout: 100 * time.Millisecond,
})

Provide(i, NewMyPostgresqlConnection)
_ = MustInvoke(i, *MyPostgresqlConnection)

status := i.HealthCheckWithContext(ctx)
// {
// "*github.com/samber/example.MyPostgresqlConnection": "DI: health check timeout: context deadline exceeded",
// }
```
4 changes: 3 additions & 1 deletion docs/docs/service-lifecycle/shutdowner.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ sidebar_position: 2

If your service brings a state such as a connection pool, a buffer, etc... you might want to close or flush it gracefully on the application exit.

When the `injector.Shutdown()` function is called, the framework triggers `Shutdown` method of each service implementing a `Shutdowner` interface, in reverse invocation order.
When the `do.Shutdown[type]()` or the `injector.Shutdown()` function is called, the framework triggers `Shutdown` method of each service implementing a `do.Shutdowner` interface, in reverse invocation order.

🛑 Services can be shutdowned properly, in back-initialization order. Requesting a shutdown on a (root?) scope shutdowns its children recursively.

## Trigger shutdown

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/service-registration/_category_.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"label": "Service registration",
"label": "📒 Service registration",
"position": 1,
"link": {
"type": "generated-index",
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/service-registration/lazy-loading.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ sidebar_position: 1

Lazy loading limits the number of components that load in an app.

🚀 Lazy services are loaded in invocation order.

🐎 Lazy service invocation is protected against concurrent loading.

## Provider

A lazy service must be defined with a `provider` (kind of constructor). This provider will be called once and must return the singleton or an error.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/troubleshooting/_category_.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"label": "Troubleshooting",
"label": "🕵️ Troubleshooting",
"position": 5,
"link": {
"type": "generated-index",
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/upgrading/_category_.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"label": "Upgrading",
"label": "🔁 Upgrading",
"position": 7,
"link": {
"type": "generated-index",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
title: To samber/do v2
description: Upgrade to samber/do v2
title: From v1.x to v2
description: Upgrade samber/do from v1.x to v2
sidebar_position: 1
---

# To samber/do v2
# Upgrade samber/do from v1.x to v2

This documentation will help you upgrade your application from `samber/do` v1 to `samber/do` v2.

`samber/do` v2 is a new major version, including breaking changes requiring you to adjust your applications accordingly. We will guide to during this process, and also mention a few optional recommendations.
`samber/do` v2 is a new major version, including breaking changes requiring you to adjust your applications accordingly. We will guide to during this process and also mention a few optional recommendations.

This release is large rewrite, but the breaking changes are relatively easy to handle. Some updates can be done with a simple `sed` command.
This release is a large rewrite, but the breaking changes are relatively easy to handle. Some updates can be done with a simple `sed` command.

Check the release notes [here](https://github.com/samber/do/releases).

Expand Down
2 changes: 1 addition & 1 deletion docs/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type * as Preset from '@docusaurus/preset-classic';

const config: Config = {
title: 'do',
tagline: 'Dependency injection for Go',
tagline: 'Typesafe dependency injection for Go',
favicon: 'img/favicon.ico',

// Set the production url of your site here
Expand Down
2 changes: 1 addition & 1 deletion docs/src/components/HomepageFeatures/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const FeatureList: FeatureItem[] = [
description: (
<>
Debugging IoC can be painful.
DO offer an API to describe application layout easily, and visualize
DO offers an API to describe application layout easily, and visualize
a service with all its dependency tree.
</>
),
Expand Down
Loading

0 comments on commit b72e0d5

Please sign in to comment.