initialize method

  1. @override
Future<AtPersistenceBundle> initialize(
  1. String atSign,
  2. AtPersistenceConfig config
)
override

Build a fully-initialised AtPersistenceBundle for atSign.

Calling this twice for the same atSign with the same storage locations returns the same bundle — the factory owns the per-atSign lifecycle. Callers should not try to manage it themselves.

Calling it for an atSign that already has an open bundle rooted somewhere else throws a StateError. One bundle per atSign is this interface's contract and bundleFor and closeFor both key on the atSign alone, so there is nowhere for a second bundle to live; returning the one it holds would answer a caller with another store's records, and the caller has no way to notice. Close the first bundle, or use a separate factory instance.

Two spellings of one location are one location: the comparison is lexical first and resolves symlinks on disagreement, so foo/bar and foo/./bar, and a link and its target, are not a conflict.

If a previous bundle for atSign has been closed (whether directly via AtPersistenceBundle.close or via closeFor), the stale entry is dropped and a fresh bundle is built — at whatever locations the new config names.

Throws ArgumentError if config does not match backendId.

Implementation

@override
Future<AtPersistenceBundle> initialize(
    String atSign, AtPersistenceConfig config) async {
  if (config is! DualWritePersistenceConfig) {
    throw ArgumentError('DualWriteAtPersistenceFactory expects '
        'DualWritePersistenceConfig, got ${config.runtimeType}');
  }
  final existing = _bundles[atSign];
  if (existing != null && !existing.isClosed) {
    final held = _configs[atSign];
    if (held != null) {
      // Raised against the ARM that differs, never against the wrapper.
      // DualWritePersistenceConfig delegates every path getter to its
      // primary, so describing the difference from the wrapper finds none
      // when it is the secondary that moved, and falls back to printing the
      // primary's path as both the held and the requested location — a
      // refusal that reads "at X, and was asked for one at X" for exactly
      // the case this comparison exists to catch.
      if (!sameStorageLocations(held.primary, config.primary)) {
        throw conflictingStorageError(
            factory: 'DualWriteAtPersistenceFactory (primary arm)',
            atSign: atSign,
            held: held.primary,
            requested: config.primary);
      }
      if (!sameStorageLocations(held.secondary, config.secondary)) {
        throw conflictingStorageError(
            factory: 'DualWriteAtPersistenceFactory (secondary arm)',
            atSign: atSign,
            held: held.secondary,
            requested: config.secondary);
      }
    }
    return existing;
  }
  if (existing != null) {
    _bundles.remove(atSign);
    _configs.remove(atSign);
  }

  final primary = await primaryFactory.initialize(atSign, config.primary);
  final secondary =
      await secondaryFactory.initialize(atSign, config.secondary);
  final bundle = DualWriteBundle._(atSign, primary, secondary);
  _bundles[atSign] = bundle;
  _configs[atSign] = config;
  return bundle;
}