Esempio n. 1
0
        private async Task <BoolResult> PublishContentHashListAsync(
            Context context,
            StrongFingerprint strongFingerprint,
            ContentHashListWithDeterminism contentHashList,
            CancellationToken token)
        {
            Contract.Assert(!_hasBeenMarkedForShutdown, "Should not queue publish operations after the session has been marked for shutdown");

            var publishingOperation = new PublishingOperation
            {
                StrongFingerprint = strongFingerprint,
                ContentHashListWithDeterminism = contentHashList
            };

            var addResult = _pendingPublishingOperations.TryAdd(publishingOperation, Interlocked.Increment(ref _orderNumber));

            if (!addResult)
            {
                // Since the operation is already pending, we return success. It's important to note that ordering matters, since
                // publishing can overwrite the remote.
                // Example of how ordering matters:
                //  These operations are queued in this order.
                //      Publish SF(A) with CHL(A)
                //      Publish SF(A) with CHL(B)
                //      Publish SF(A) with CHL(A)
                //  If we followed the queuing order and the remote was being overwritten by every call, the end result is SF(A)->CHL(A).
                //  If we eliminate duplicates, and the first operation is still pending while we queue the third one, the result is SF(A)->CHL(B).
                // For now, we are willing to take chanses and ocassionally publish CHLs out of order.
                return(BoolResult.Success);
            }

            var result = await _remote.PublishContentHashListAsync(
                context,
                strongFingerprint,
                contentHashList,
                token);

            _pendingPublishingOperations.TryRemove(publishingOperation, out _);

            // Make sure that we unblock shutdown once all publishing operations have been completed.
            if (_hasBeenMarkedForShutdown && _pendingPublishingOperations.Count == 0)
            {
                _readyForShutdown.TrySetResult(true);
            }

            return(result);
        }
Esempio n. 2
0
        private async Task <BoolResult> PublishContentHashListAsync(
            Context context,
            StrongFingerprint strongFingerprint,
            ContentHashListWithDeterminism contentHashList,
            CancellationToken token)
        {
            var publishingOperation = new PublishingOperation
            {
                StrongFingerprint = strongFingerprint,
                ContentHashListWithDeterminism = contentHashList
            };

            var addResult = _pendingPublishingOperations.TryAdd(publishingOperation, Interlocked.Increment(ref _orderNumber));

            if (!addResult)
            {
                // Since the operation is already pending, we return success. It's important to note that ordering matters, since
                // publishing can overwrite the remote.
                // Example of how ordering matters:
                //  These operations are queued in this order.
                //      Publish SF(A) with CHL(A)
                //      Publish SF(A) with CHL(B)
                //      Publish SF(A) with CHL(A)
                //  If we followed the queuing order and the remote was being overwritten by every call, the end result is SF(A)->CHL(A).
                //  If we eliminate duplicates, and the first operation is still pending while we queue the third one, the result is SF(A)->CHL(B).
                // For now, we are willing to take chanses and ocassionally publish CHLs out of order.
                return(BoolResult.Success);
            }

            var result = await _remote.PublishContentHashListAsync(
                context,
                strongFingerprint,
                contentHashList,
                token);

            _pendingPublishingOperations.TryRemove(publishingOperation, out _);

            return(result);
        }