/// <summary> /// 延时关闭Socket, 保证所有的事务都执行完毕 /// </summary> /// <param name="sock"></param> public static void DelayClose(RpcTcpSocketConnection sock) { DateTime t = DateTime.Now.AddSeconds(_delayCloseSeconds); _tracing.InfoFmt("enqueue delay close connection: {0} in {1}", sock.RemoteUri, t); _counter.ConnectionsRecycled.Increment(); sock.Recycling = true; lock (_syncRoot) { _closeQueue.Enqueue(new ComboClass <DateTime, RpcTcpSocketConnection>(t, sock)); } }
private void CheckAndRunNext(TccRunningContext <TContext> rc) { if (rc != null) { _txState = rc.NextState; if (_txState == TccTransactionState.Confirmed) { if (_coordinator != null) { _coordinator.CloseTransaction(this); } _txCtx.Return(); return; } else if (_txState == TccTransactionState.Cancelled) { if (_coordinator != null) { _coordinator.CloseTransaction(this); } _txCtx.ThrowException("Transaction Cancelled", GetFirstError()); return; } else if (_txState == TccTransactionState.ConfirmFailed || _txState == TccTransactionState.CancelFailed) { if (_coordinator != null) { _coordinator.CloseTransaction(this); } _txCtx.ThrowException("Transaction Failed", GetFirstError()); return; } else { if (_coordinator != null) { _coordinator.UpdateTransaction(this); } } } lock (_syncRoot) { rc = GetRunningContext(); } _tracing.InfoFmt("NextRunningContext() = {0}", rc); rc.Run( delegate() { try { CheckAndRunNext(rc); } catch (Exception ex) { _tracing.Error(ex, "CheckAndRunNext() Failed"); _txCtx.ThrowException("TccTransaction.CheckAndRunNext() Failed", ex); } } ); }
internal void RunAction(TContext context, TccAction nextAction, Action <Exception> callback) { Action <TccWorkUnitContext <TContext> > Proc; TccWorkState succState; TccWorkState failState; Tracing.InfoFmt("WorkUnit<{0}>.Run{1} State:{2}", _workName, nextAction, _state); switch (nextAction) { case TccAction.Try: if (_state != TccWorkState.None) { throw new Exception("Unexcepted WorkUnit State:" + _state); } _state = TccWorkState.Trying; Proc = Try; succState = TccWorkState.Tryed; failState = TccWorkState.TryFailed; break; case TccAction.Confirm: if (_state != TccWorkState.Tryed) { throw new Exception("Unexcepted WorkUnit State:" + _state); } Proc = Confirm; _state = TccWorkState.Confirming; succState = TccWorkState.Confirmed; failState = TccWorkState.ConfirmFailed; break; case TccAction.Cancel: if (_state != TccWorkState.Tryed && _state != TccWorkState.TryFailed) { throw new Exception("Unexcepted WorkUnit State:" + _state); } Proc = Cancel; _state = TccWorkState.Cancelling; succState = TccWorkState.Cancelled; failState = TccWorkState.CancelFailed; break; default: throw new Exception("NeverGoHere"); } int hasReturned = 0; TccWorkUnitContext <TContext> ctx = new TccWorkUnitContext <TContext>( context, delegate(Exception ex) { if (ex != null) { Tracing.ErrorFmt(ex, "WorkUnit<{0}>.Run{1} Failed in callback.", _workName, nextAction); } else { Tracing.InfoFmt("WorkUnit<{0}>.Run{1} ok.", _workName, nextAction); } if (Interlocked.CompareExchange(ref hasReturned, 1, 0) == 0) { if (ex == null) { _state = succState; callback(null); } else { _error = ex; _state = failState; callback(ex); } } else { Tracing.ErrorFmt("WorkUnit<{0}>.Run{1} callback return more than once.", _workName, nextAction); } } ); try { Proc(ctx); } catch (Exception ex) { if (Interlocked.CompareExchange(ref hasReturned, 1, 0) == 0) { Tracing.ErrorFmt(ex, "WorkUnit<{0}>.Run{1} Failed.", _workName, nextAction); _error = ex; _state = failState; callback(ex); } else { Tracing.ErrorFmt("WorkUnit<{0}>.Run{1} return more than once.", _workName, nextAction); } } }