public virtual IReplica?TryGet(PublicationRef publicationRef) { var random = publicationRef.PublicationId.HashCode; OnOperation(random); if (!_handles.TryGetValue(publicationRef, out var handle)) { return(null); } var target = (IReplica?)handle.Target; if (target != null) { return(target); } // GCHandle target == null => we have to recycle it if (!_handles.TryRemove(publicationRef, handle)) { // Some other thread already removed this entry return(null); } // The thread that succeeds in removal releases gcHandle as well _gcHandlePool.Release(handle, random); return(null); }
public virtual (IReplica Replica, bool IsNew) GetOrRegister(PublicationRef publicationRef, Func <IReplica> replicaFactory) { var random = publicationRef.PublicationId.HashCode; OnOperation(random); var spinWait = new SpinWait(); var newReplica = (IReplica?)null; // Just to make sure we store this ref while (true) { // ReSharper disable once HeapView.CanAvoidClosure var handle = _handles.GetOrAdd(publicationRef, _ => { newReplica = replicaFactory.Invoke(); return(_gcHandlePool.Acquire(newReplica, random)); }); var target = (IReplica?)handle.Target; if (target != null) { if (target == newReplica) { return(target, true); } (newReplica as IReplicaImpl)?.DisposeTemporaryReplica(); return(target, false); } // GCHandle target == null => we have to recycle it if (_handles.TryRemove(publicationRef, handle)) { // The thread that succeeds in removal releases gcHandle as well _gcHandlePool.Release(handle, random); } // And since we didn't manage to add the replica, let's retry spinWait.SpinOnce(); } }
public IReplica?TryGet(PublicationRef publicationRef) => ReplicaRegistry.Instance.TryGet(publicationRef);
public ReplicaInput(IReplicaImpl replicaImpl, PublicationRef publicationRef) : base(replicaImpl) { ReplicaImpl = replicaImpl; PublicationRef = publicationRef; }
public static IReplica <T> GetOrAdd <T>(this IReplicator replicator, PublicationRef publicationRef, bool requestUpdate = false) { var output = new Result <T>(default !, ReplicaHasBeenNeverUpdatedError);
public PublicationStateInfo(PublicationRef publicationRef) => PublicationRef = publicationRef;