public TContext PrepareVersion(UpdateVersionContext update, ISourceQueue <TInput> inputQueue, ITargetQueue <TOutput> outputQueue, TContextConfig setup, Action <TContext, bool> prepareContext = null, int uniqueVersionsLimit = int.MaxValue) { update.RuntimeConfig.Add(this, setup); var last = _versions.Last?.Value;// no need to sync as it is changed from the same thread bool sameConfig = last != null && last.ContextSetup.Equals(setup); int uniqueVersion = last?.UniqueContextVersion ?? 0; if (!sameConfig) { uniqueVersion++; if (last != null) { Core.LogInfo($"Change {Name}: {last.ContextSetup} >> {setup}"); } else { Core.LogInfo($"Change {Name}: >> {setup}"); } } var ctx = sameConfig ? last.Context.AddRef() : CreateAndOpenContextRef(setup); ContextVersion <TContext, TContextConfig, TOutput> pending = new ContextVersion <TContext, TContextConfig, TOutput> { Version = update.Version, Context = ctx, ContextSetup = setup, OutputQueue = outputQueue, UniqueContextVersion = uniqueVersion }; update.AddDeploy(() => { lock (this) { if (_versions.Last != null) { _versions.Last.Value.TimeWhenOutdated = DateTime.UtcNow; } _versions.AddLast(pending); InputQueue = inputQueue; if (inputQueue != null) { InputQueue.OnChanged = Activate; } prepareContext?.Invoke(pending.Context.Instance, sameConfig); _uniqueVersionsLimit = uniqueVersionsLimit; TryRemoveOldVersions(); } }); return(pending.Context.Instance); }
public TContext PrepareVersion(UpdateVersionContext version, int instances, ISourceQueue <TInput> inputQueue, Func <UpdateVersionContext, Node <TContext, TContextConfig, TInput, TOutput>, TContext> prepareContext) { version.RuntimeConfig.Add(this, null); var pendingNodesToAdd = new List <Node <TContext, TContextConfig, TInput, TOutput> >(); if (_nodes.Count != instances) { Core.LogInfo($"Changing number of pooled nodes for {Name} from {_nodes.Count} to {instances}"); } while (_nodes.Count + pendingNodesToAdd.Count < instances) { var newNode = _creator(_nodes.Count + pendingNodesToAdd.Count); pendingNodesToAdd.Add(newNode); } TContext result = default; foreach (var item in _nodes) { result = prepareContext(version, item); } foreach (var item in pendingNodesToAdd) { result = prepareContext(version, item); } version.AddDeploy(() => { lock (this) { InputQueue = inputQueue; InputQueue.OnChanged = ActivateFromPool; pendingNodesToAdd.ForEach(s => _runtimeNodes.Push(s)); _nodes.AddRange(pendingNodesToAdd); while (_nodes.Count > instances) { _nodesToRemove.Add(_nodes[0]); _nodes.RemoveAt(0); } } }); return(result); }