How to implement server and client middlewares:
There is a main component that manages a middlewares pipeline.
These components allow you to globally enable/disable middlewares. There isn't one explicit global ordered list of middlewares. That approach is not flexible and not scalable. Instead, each middleware can provide an information of position relative to other middlewares. Each middleware sets some dependency order relative to other middlewares using middlewares::MiddlewareDependencyBuilder. Then Pipeline collects that set of dependencies between middlewares and builds DAG (directed acyclic graph). Then Pipeline builds an ordered middlewares list from that DAG.
You can enable/disable middleware per service or per client. For more information see Enable/disable middlewares.
Each middleware belongs to some group. You need to start defining the order of middleware from a group of that middleware.
Groups:
The pipeline calls middlewares in that order. PreCore
group is called first, then Logging
and so forth. User
group is called the last one. User
group is the default group for all middlewares.
There are Post-hooks and Pre-hooks for each middleware interface. Post-hooks are always called in the reverse order. For more information see special implementation of server or client middlewares:
If your middleware doesn't care about an order, your middleware will be in the User
group by default.
To specify middleware group and dependencies, you should use middlewares::MiddlewareDependencyBuilder
.
Each middleware is in the middlewares::groups::User group by default.
If your middleware component is inherited from ugrpc::{client,server}::MiddlewareFactoryComponentBase
, you can choose some group for that middleware and pass it in the MiddlewareFactoryComponentBase
constructor:
If your middleware component is a short-cut ugrpc::{server, client}::SimpleMiddlewareFactoryComponent
, you can choose some group with kDependency
field:
Now the middleware of MetaFilterComponent will be ordered after ugrpc::server::middlewares::headers_propagator::Component
. You can create dependencies between middlewares only if they are in the same group, otherwise there will be an exception on the start of the service.
Also, you can use the method middlewares::MiddlewareDependencyBuilder::Before
. You can use methods Before
/After
together and effect will be accumulated. E.g. A.Before<B>().After<C>()
⇒ order from left to right: C, A, B.
E.g. there are one independent middleware and two chains: A.After<Z>
and C.After<B>
. Final order is B, Z, A, C, F
.
What happens if some MiddlewareA
requires After<MiddlewareB>()
and MiddlewareB
is disabled?
If the After
method was called without arguments, there will be a fatal error at the start of the service.
If you want to skip this dependency in that case, just pass it middlewares::DependencyType::kWeak
in After
.