/// <summary> /// accept friendship /// </summary> /// <returns></returns> public async Task Accept() { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"accept()"); } if (Payload == null) { throw new InvalidOperationException("no payload"); } if (Payload.Type != FriendshipType.Receive) { throw new InvalidOperationException($"accept() need type to be FriendshipType.Receive, but it got a {Payload.Type}"); } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"accept() to {Payload.ContactId}"); } await Puppet.FriendshipAccept(Id); var contact = Contact; await Policy.Handle <Exception>() .WaitAndRetryAsync(10, (attempt) => TimeSpan.FromSeconds((1d - new Random().NextDouble()) * Math.Pow(2, attempt)), (exception, attempt) => { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"accept() retry() ready() attempt {attempt}"); } }).ExecuteAsync(async() => { await contact.Ready(); if (IsReady) { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"accept() with contact {contact.Name} ready()"); } return; } throw new InvalidOperationException("Friendship.accept() contact.ready() not ready"); }).ContinueWith(task => { if (task.IsFaulted) { Logger.LogWarning($"accept() contact {contact} not ready because of {task.Exception?.Message}"); } }); await contact.Sync(); }