Skip to content

RubyEventStore configuration - a new way to handle upcoming features - #1908

Open
mpraglowski wants to merge 11 commits into
masterfrom
configuration
Open

RubyEventStore configuration - a new way to handle upcoming features#1908
mpraglowski wants to merge 11 commits into
masterfrom
configuration

Conversation

@mpraglowski

Copy link
Copy Markdown
Member

An attempt speedup releases by adding feature flags based on
configuration defined. By using load_defaults dev will still be able to
keep the RES behaviour as is, without changes and new installations
will use new features hidden behind configuration flags.

An attempt speedup releases by adding feature flags based on
configuration defined. By using load_defaults dev will still be able to
keep the RES behaviour as is, without changes and new installations
will use new features hidden behind configuration flags.
Changing a default in a released gem is a breaking change, so new defaults
either wait for a major bump or force everyone to adapt at upgrade time.
Following Rails' load_defaults removes that tradeoff: upgrading the gem no
longer changes behaviour, and each new default can be adopted separately,
once the app is ready for it.

Client no longer hardcodes its defaults — repository, mapper, subscriptions,
dispatcher, broker, event type resolver, clock and correlation id generator
now come from the configuration. Stateful collaborators are configured as
factories, so every Client still gets its own instances.

The "3.0" defaults are the values Client used until now, which makes this
change a no-op for existing applications. Unknown versions raise instead of
silently falling back, so a typo in load_defaults is not mistaken for an
opt-out.
Same reasoning as for RubyEventStore::Client: upgrading the gem must not
change behaviour, and a new default should be adoptable on its own.
RailsEventStore has its own defaults — instrumented collaborators, the
ActiveRecord repository, after commit dispatching, request metadata — so it
gets its own Configuration, inheriting the core defaults and overriding what
Rails does differently.

Instrumentation stays in the Client, so anything passed in by hand is still
wrapped; only the defaults come ready-made from the configuration.

The serializer becomes a configuration entry — it was spelled out twice, in
the repository and in the ActiveJob scheduler, which made moving off YAML a
change in two unrelated places.

The "3.0" defaults are the values the client used until now, so existing
applications see no difference.
The defaults branch was keyed to "3.0", a number that does not describe what
it holds — these defaults have not shipped in any version yet. Naming a
version before it exists means the branch is either wrong until the release
lands, or right by accident.

The branch of the version being worked on is now matched dynamically, and
`make set-version` freezes it under the number actually being released. The
release step that used to be easy to forget is no longer a step at all.

Version dispatch drops out of RailsEventStore::Configuration — it only
overrides the loader and calls super, so the two gems cannot drift into
disagreeing about which version a default belongs to. This also fixes core
defaults being skipped entirely: the subclass loader was overriding the one
super called, so mapper, clock, correlation id generator and event type
resolver were never set for Rails clients.
Branches are now matched from the newest down with `>=`,
so only a version which changes something gets one and everything
released after it loads what that one left behind.

Defaults belong to a major.minor version — a patch release cannot change
behaviour, so it must not name defaults of its own.

Freezing moves from sed to support/release/freeze_defaults, which also puts
an empty upcoming branch back in place. This automates preparation for
upcoming changes in future versions.
Configuration gains a variant, the kind of client defaults are loaded for.
The :json variant carries the JSON serializer and the type preserving mapper used until now by JSONClient, so existing applications see no difference.
The configuration is memoized on first use and its variant is settled then,
so an example's outcome depended on which kind of client another example
happened to build first — JSONClient specs passed alone and failed in a full run.
It will setup base configuration variant.
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.

1 participant