Skip to content

fix: activate a plugin's hooks only after it has registered - #334

Closed
abelonogov-ld wants to merge 1 commit into
mainfrom
andrey/register-plugin-hook-order
Closed

fix: activate a plugin's hooks only after it has registered#334
abelonogov-ld wants to merge 1 commit into
mainfrom
andrey/register-plugin-hook-order

Conversation

@abelonogov-ld

@abelonogov-ld abelonogov-ld commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #278, aligning Flutter with the same change going into the iOS and Android client SDKs (launchdarkly/ios-client-sdk#525).

A plugin's hooks now go live only once every plugin has registered, rather than before register is called. That has two effects:

  • A plugin's own hooks no longer observe the flag evaluations its register makes.
  • One plugin's hooks no longer observe another plugin's register, which previously depended on where each plugin sat in LDConfig.plugins.

The plugins configured on LDConfig and those passed to registerPlugin now both go through safeRegisterPlugins, so the two paths cannot drift apart again. safeRegisterPlugins takes an addHook callback and activates the collected hooks as its last step; safeRegisterPlugin is the single plugin case and simply delegates.

A plugin that throws from either hooks or register now contributes no hooks, where before a failing register left its hooks in place.

This does not change when hooks are ready relative to the first identify: registration still completes inside the constructor, well before start() opens the initial identify series.

Test plan

  • common_client: 24 tests pass, including new coverage that hooks are activated in plugin order and that a plugin failing to register contributes none
  • flutter_client_sdk: full suite passes (51 tests)
  • dart analyze / flutter analyze clean on both packages
  • Updated adds hooks only after plugin register has returned (was asserting the old ordering) and added plugin hooks do not observe another plugin register

Note

Overview
Plugin hooks are no longer wired in before register runs. safeRegisterPlugins now registers every plugin first, collects hooks only from plugins that succeed, then calls addHook for all of them in one pass—so hooks never see another plugin’s register work (including flag evaluations during registration). safeRegisterPlugin is the single-plugin entry point that delegates to the same path.

On LDClient, construction passes only config.hooks into the common client; plugin hooks are added afterward via safeRegisterPlugins(..., addHook, ...). registerPlugin uses safeRegisterPlugin instead of activating hooks before register. A plugin that throws from hooks or register contributes no hooks (previously a failed register could still leave hooks active).

Config-time and runtime plugin registration share one code path, aligning Flutter with the iOS/Android SDK change. Hook readiness relative to the first identify is unchanged—registration still finishes in the constructor before start().

Reviewed by Cursor Bugbot for commit 9e2bf0f. Bugbot is set up for automated code reviews on this repo. Configure here.

A plugin's hooks now go live once every plugin has registered, rather than
before register is called. This keeps a plugin's own hooks from observing what
its register does, and keeps one plugin's hooks from observing another plugin's
register regardless of list order.

Both the plugins configured on LDConfig and those passed to registerPlugin now
go through safeRegisterPlugins, so the two paths cannot drift apart.

Co-authored-by: Cursor <cursoragent@cursor.com>
@abelonogov-ld
abelonogov-ld requested a review from a team as a code owner August 25, 2026 22:11

@kinyoklion kinyoklion left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description of this PR specifically violates the design of hooks/plugins. Which is two phases to ensures that plugins can specifically observe evaluations of themselves and other plugins. Though if a specific plugin wishes to not do that, it could be possible.

https://github.com/launchdarkly/sdk-specs/tree/main/specs/PLUGIN-sdk-plugin-support#requirement-116

If nothing else spec changes need to come before code changes, and the spec isn't changed.

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.

2 participants