示例#1
0
        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);
        }
示例#2
0
        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();
            }
        }
示例#3
0
 public IReplica?TryGet(PublicationRef publicationRef)
 => ReplicaRegistry.Instance.TryGet(publicationRef);
示例#4
0
 public ReplicaInput(IReplicaImpl replicaImpl, PublicationRef publicationRef)
     : base(replicaImpl)
 {
     ReplicaImpl    = replicaImpl;
     PublicationRef = publicationRef;
 }
示例#5
0
 public static IReplica <T> GetOrAdd <T>(this IReplicator replicator,
                                         PublicationRef publicationRef, bool requestUpdate = false)
 {
     var output = new Result <T>(default !, ReplicaHasBeenNeverUpdatedError);
示例#6
0
 public PublicationStateInfo(PublicationRef publicationRef)
 => PublicationRef = publicationRef;