public void Initialize( CommandLineOptions options, PrivateKey privateKey, Action <bool> callback) { PrivateKey = privateKey; _channel = new Channel( options.RpcServerHost, options.RpcServerPort, ChannelCredentials.Insecure, new[] { new ChannelOption("grpc.max_receive_message_length", -1) } ); _lastTipChangedAt = DateTimeOffset.UtcNow; _hub = StreamingHubClient.Connect <IActionEvaluationHub, IActionEvaluationHubReceiver>(_channel, this); _service = MagicOnionClient.Create <IBlockChainService>(_channel); _genesis = BlockManager.ImportBlock(options.GenesisBlockPath ?? BlockManager.GenesisBlockPath); var appProtocolVersion = options.AppProtocolVersion is null ? default : Libplanet.Net.AppProtocolVersion.FromToken(options.AppProtocolVersion); AppProtocolVersion = appProtocolVersion.Version; RegisterDisconnectEvent(_hub); StartCoroutine(CoTxProcessor()); StartCoroutine(CoJoin(callback)); }
private async void RegisterDisconnectEvent(IActionEvaluationHub hub) { try { await hub.WaitForDisconnect(); } finally { RetryRpc(); } }
private async void RetryRpc() { OnRetryStarted.OnNext(this); var retryCount = 10; Debug.Log($"Retry rpc connection. (count: {retryCount})"); while (retryCount > 0) { await Task.Delay(5000); _hub = StreamingHubClient.Connect <IActionEvaluationHub, IActionEvaluationHubReceiver>(_channel, this); try { Debug.Log($"Trying to join hub..."); await _hub.JoinAsync(); Debug.Log($"Join complete! Registering disconnect event..."); RegisterDisconnectEvent(_hub); UpdateSubscribeAddresses(); OnRetryEnded.OnNext(this); return; } catch (RpcException re) { Debug.LogWarning($"RpcException occurred. Retrying... {retryCount}\n{re}"); retryCount--; } catch (ObjectDisposedException ode) { Debug.LogWarning($"ObjectDisposedException occurred. Retrying... {retryCount}\n{ode}"); retryCount--; } catch (Exception e) { Debug.LogWarning($"Unexpected error occurred during rpc connection. {e}"); break; } } Connected = false; OnDisconnected.OnNext(this); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1000, stoppingToken); _client = StreamingHubClient.Connect <IActionEvaluationHub, IActionEvaluationHubReceiver>( new Channel(_host, _port, ChannelCredentials.Insecure), null ); await _client.JoinAsync(); _blockRenderer.EveryBlock().Subscribe( async pair => await _client.BroadcastRenderBlockAsync( pair.OldTip.Header.Serialize(), pair.NewTip.Header.Serialize() ), stoppingToken ); _blockRenderer.EveryReorg().Subscribe( async ev => await _client.ReportReorgAsync( ev.OldTip.Serialize(), ev.NewTip.Serialize(), ev.Branchpoint.Serialize() ), stoppingToken ); _blockRenderer.EveryReorgEnd().Subscribe( async ev => await _client.ReportReorgEndAsync( ev.OldTip.Serialize(), ev.NewTip.Serialize(), ev.Branchpoint.Serialize() ), stoppingToken ); _actionRenderer.EveryRender <ActionBase>() .Where(ContainsAddressToBroadcast) .Subscribe( async ev => { var formatter = new BinaryFormatter(); using var c = new MemoryStream(); using var df = new DeflateStream(c, System.IO.Compression.CompressionLevel.Fastest); try { formatter.Serialize(df, ev); await _client.BroadcastRenderAsync(c.ToArray()); } catch (SerializationException se) { // FIXME add logger as property Log.Error(se, "Skip broadcasting render since the given action isn't serializable."); } catch (Exception e) { // FIXME add logger as property Log.Error(e, "Skip broadcasting render due to the unexpected exception"); } }, stoppingToken ); _actionRenderer.EveryUnrender <ActionBase>() .Where(ContainsAddressToBroadcast) .Subscribe( async ev => { var formatter = new BinaryFormatter(); using var c = new MemoryStream(); using var df = new DeflateStream(c, System.IO.Compression.CompressionLevel.Fastest); try { formatter.Serialize(df, ev); await _client.BroadcastUnrenderAsync(c.ToArray()); } catch (SerializationException se) { // FIXME add logger as property Log.Error(se, "Skip broadcasting unrender since the given action isn't serializable."); } catch (Exception e) { // FIXME add logger as property Log.Error(e, "Skip broadcasting unrender due to the unexpected exception"); } }, stoppingToken ); _exceptionRenderer.EveryException().Subscribe( async tuple => { var(code, message) = tuple; await _client.ReportExceptionAsync((int)code, message); }, stoppingToken ); _nodeStatusRenderer.EveryChangedStatus().Subscribe( async isPreloadStarted => { if (isPreloadStarted) { await _client.PreloadStartAsync(); } else { await _client.PreloadEndAsync(); } }, stoppingToken ); }