private void Gateway_OnFailure(object sender, GatewayFailureData e) { isRunning = false; CleanUp(); OnFailure?.Invoke(this, new ShardFailureEventArgs(this, e.Message, e.Reason, e.Exception)); stoppedResetEvent.Set(); }
/// <summary> /// Starts this shard. /// The returned task only finishes once the gateway successfully connects (or is canceled), /// and will continue to retry until then. /// </summary> /// <param name="config">A set of options to use when starting the shard.</param> /// <exception cref="ArgumentNullException">Thrown if config is null.</exception> /// <exception cref="InvalidOperationException">Thrown if this shard has already been started.</exception> /// <exception cref="ObjectDisposedException">Thrown if this shard has been disposed.</exception> /// <exception cref="OperationCanceledException"></exception> /// <exception cref="ShardStartException">Thrown if the shard fails to start.</exception> public async Task StartAsync(ShardStartConfig config, CancellationToken?cancellationToken = null) { if (isDisposed) { throw new ObjectDisposedException(nameof(gateway), "Shard has been disposed."); } if (config == null) { throw new ArgumentNullException(nameof(config)); } if (!isRunning) { isRunning = true; CleanUp(); CancellationToken ct = cancellationToken ?? CancellationToken.None; try { await gateway.ConnectAsync(config, ct).ConfigureAwait(false); } catch (GatewayHandshakeException ex) { isRunning = false; CleanUp(); stoppedResetEvent.Set(); GatewayFailureData failureData = ex.FailureData; throw new ShardStartException(failureData.Message, this, failureData.Reason, failureData.Exception); } catch { isRunning = false; CleanUp(); stoppedResetEvent.Set(); throw; } log.LogInfo("Successfully connected to the Gateway."); stoppedResetEvent.Reset(); OnConnected?.Invoke(this, new ShardEventArgs(this)); } else { throw new InvalidOperationException($"Shard {Id} has already been started!"); } }