/// <summary> /// sets the txid and time for this locklist /// </summary> /// <param name="over">optional, the overrides</param> private void SetTxIdAndTime(IOperationOverrides over) { if (over != null && over.TxId != ulong.MaxValue) { this.TxId = (long)over.TxId; } if (over != null && over.TxTime != ulong.MaxValue) { this.TxTime = (long)over.TxTime; } else { this.TxTime = MutableStat.ConvertTime(DateTime.UtcNow); } }
/// <summary> /// performs the actions on apply, and maybe run the scheduled action /// </summary> /// <param name="txtime">the time the transaction has</param> /// <param name="xid">the id for the transaction</param> /// <param name="func">the function to run</param> /// <param name="onMultiples">if true, this is only a run in multiples of</param> private void DoActionsOnApply(long txtime, long xid, RunOnTxIdMultiplesFunction func, bool onMultiples = true) { // if we already saw this txid (multiple calls to DoActionsOnApply per txid are possible), exit now if (xid == this.lastTxRun) { return; } // if we are still loading, exit now if (this.ThisReplicaName == null) { return; } // first produce an instrumentation signal indicating we are applying this transaction RingMasterServerInstrumentation.Instance.OnApply(txtime, xid); // if we don't have a function, exit now if (func == null) { return; } // we only run the periodic action if we have a proper configuration, and it is time to run it based on such config if (onMultiples && (this.runOnTxIdMultiplesOf == 0 || (xid % this.runOnTxIdMultiplesOf) != 0)) { return; } // if the time is too off, exit if (Math.Abs((DateTime.UtcNow - MutableStat.ConvertTime(txtime)).TotalSeconds) > 60) { Trace.TraceInformation("skipping action because it likely comes from the past"); return; } // set the last txid seen this.lastTxRun = xid; // do the action func(txtime, xid); }
/// <summary> /// runs the command from the path /// </summary> /// <param name="req">the request containing the command</param> /// <param name="session">the session this command was run from</param> /// <param name="lockList">the lock list of the invocation</param> /// <returns>the repsonse to the command</returns> internal virtual RequestResponse RunCommand(RequestCreate req, ClientSession session, ILockListTransaction lockList) { if (req == null) { throw new ArgumentNullException(nameof(req)); } if (session == null) { throw new ArgumentNullException(nameof(session)); } MutableStat stat = new MutableStat(new FirstStat(0, MutableStat.ConvertTime(DateTime.UtcNow), 0)); // we require the digest 'Commander' if (!string.Equals(session.Auth.ClientDigest, CommanderDigest, StringComparison.InvariantCultureIgnoreCase)) { return(new RequestResponse() { Content = "not executed", ResponsePath = "command", ResultCode = (int)Code.Authfailed, Stat = stat, }); } string requestedCommand; object content; Code result = this.RunCommandPath(req.Path, req.Data, session, lockList, out requestedCommand, out content); return(new RequestResponse() { Content = content, ResponsePath = requestedCommand, ResultCode = (int)result, Stat = stat, }); }