Esempio n. 1
0
        internal async ValueTask <IObjectPrx?> FindObjectAsync(Identity id)
        {
            Task <IObjectPrx?>?task = null;
            LookupReply?       replyServant;

            lock (_mutex)
            {
                if (!_objectReplies.TryGetValue(id, out replyServant))
                {
                    replyServant = new LookupReply();
                    _objectReplies.Add(id, replyServant);
                }
                else
                {
                    task = replyServant.CompletionSource.Task;
                }
            }

            if (task == null)
            {
                task = InvokeAsync(
                    async(lookup, lookupReply) =>
                {
                    try
                    {
                        await lookup.FindObjectByIdAsync(_domainId, id, lookupReply).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException(
                            $"failed to lookup object `{id}' with lookup proxy `{_lookup}'", ex);
                    }
                },
                    replyServant);

                await task.ConfigureAwait(false);

                lock (_mutex)
                {
                    _objectReplies.Remove(id);
                }
            }
            return(await task.ConfigureAwait(false));
        }
Esempio n. 2
0
        internal async Task <IObjectPrx?> InvokeAsync(Func <ILookupPrx, ILookupReplyPrx, Task> find, LookupReply replyServant)
        {
            Identity requestId = _replyAdapter.AddWithUUID(replyServant, ILocatorRegistryPrx.Factory).Identity;

            Task <IObjectPrx?> replyTask = replyServant.CompletionSource.Task;

            try
            {
                for (int i = 0; i < _retryCount; ++i)
                {
                    TimeSpan start        = Time.Elapsed;
                    int      failureCount = 0;
                    foreach ((ILookupPrx lookup, ILookupReplyPrx? reply) in _lookups)
                    {
                        ILookupReplyPrx?lookupReply = reply.Clone(requestId, ILookupReplyPrx.Factory);
                        try
                        {
                            await find(lookup, lookupReply);
                        }
                        catch (Exception ex)
                        {
                            if (++failureCount == _lookups.Count)
                            {
                                _lookup.Communicator.Logger.Warning(ex.ToString());
                                replyServant.CompletionSource.SetResult(null);
                            }
                        }
                    }

                    Task?t = await Task.WhenAny(replyTask,
                                                Task.Delay(_timeout, replyServant.CancellationSource.Token)).ConfigureAwait(false);

                    if (t == replyTask)
                    {
                        return(await replyTask.ConfigureAwait(false)); // We're done!
                    }
                    else if (t.IsCanceled)
                    {
                        // If the timeout was canceled we delay the completion of the request to give a chance to other
                        // members of this replica group to reply
                        return(await replyServant.WaitForReplicaGroupRepliesAsync(start, _latencyMultiplier));
                    }
                }
                replyServant.CompletionSource.SetResult(null); // Timeout
                return(await replyTask.ConfigureAwait(false));
            }
            finally
            {
                _replyAdapter.Remove(requestId);
            }
        }