internal LockSession(ILockManagerImplementation manager, string path, object shardingID, string description = null, int?maxAgeSec = null) { if (path.IsNullOrWhiteSpace()) { throw new LockingException(StringConsts.ARGUMENT_ERROR + "LockSession.ctor(path==null|empty)"); } if (shardingID == null) { throw new LockingException(StringConsts.ARGUMENT_ERROR + "LockSession.ctor(shardingID==null)"); } Data = new Server.LockSessionData(new LockSessionID(null), description, maxAgeSec); Manager = manager; Path = path; ShardingID = shardingID; try { var shardingHash = shardingID.GetHashCode(); var zone = manager.App.GetMetabase().CatalogReg.NavigateZone(Path); var primaryZgovs = zone .FindNearestParentZoneGovernors(iAmZoneGovernor: false, filter: (host) => !host.IsZGovLockFailover, transcendNOC: true) .OrderBy(host => host.Name) .ToArray(); if (primaryZgovs.Length < 1) { throw new LockingException(StringConsts.LOCK_SESSION_PATH_LEVEL_NO_ZGOVS_ERROR.Args(Path)); } var failoverZgovs = zone .FindNearestParentZoneGovernors(iAmZoneGovernor: false, filter: (host) => host.IsZGovLockFailover, transcendNOC: true) .OrderBy(host => host.Name) .ToArray(); if (failoverZgovs.Length > 0 && (primaryZgovs.Length != failoverZgovs.Length || !primaryZgovs[0].ParentZone.IsLogicallyTheSame(failoverZgovs[0].ParentZone)) ) { throw new LockingException(StringConsts.LOCK_SESSION_ZGOV_SETUP_ERROR.Args(primaryZgovs[0].ParentZone.RegionPath)); } var idx = (shardingHash & CoreConsts.ABS_HASH_MASK) % primaryZgovs.Length; ServerHostPrimary = primaryZgovs[idx].RegionPath; if (failoverZgovs.Length > 0) { ServerHostSecondary = failoverZgovs[idx].RegionPath; } } catch (Exception error) { throw new LockingException(StringConsts.LOCK_SESSION_PATH_ERROR.Args(Path, error.ToMessageWithType()), error); } }
public LockTransactionResult ExecuteLockTransaction(LockSessionData session, LockTransaction transaction) { var result = executeLockTransaction(session, transaction); if (m_InstrumentationEnabled) { var key = result.Status == LockStatus.TransactionOK ? "OK" //for speed not to concat strings : result.Status.ToString() + ':' + result.ErrorCause.ToString(); m_stat_ExecuteTranCalls.IncrementLong(key); } return(result); }
private LockTransactionResult executeLockTransaction(LockSessionData session, LockTransaction transaction) { if (!Running) { return(LockTransactionResult.CallFailed); } Interlocked.Increment(ref m_CurrentServerCalls); if (session == null || transaction == null) { throw new LockingException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".ExecuteLockTransaction(session|transaction==null)"); } var isPing = transaction.Statements == null; if (!isPing && transaction.Namespace.IsNullOrWhiteSpace()) { throw new LockingException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".ExecuteLockTransaction(transaction.Namespace==null|empty)"); } var sapp = App.AsSky(); var currentTrustLevel = CurrentTrustLevel; var appRunTimeSec = (uint)(DateTime.UtcNow - m_StartTimeUTC).TotalSeconds; //insufficient runtime period length or trust level if (transaction.MinimumRequiredRuntimeSec > appRunTimeSec || transaction.MinimumRequiredTrustLevel > currentTrustLevel) { return(new LockTransactionResult(transaction.ID, sapp.HostName, LockStatus.TransactionError, LockErrorCause.MinimumRequirements, null, appRunTimeSec, currentTrustLevel, null)); } var sid = session.ID.ToString(); var ss = m_Sessions.GetOrRegister(sid, (sd) => new ServerLockSession(sd), session); lock (ss) { if (ss.Disposed) { return(new LockTransactionResult(transaction.ID, sapp.HostName, LockStatus.TransactionError, LockErrorCause.SessionExpired, null, appRunTimeSec, currentTrustLevel, null)); } ss.m_LastInteractionUTC = App.TimeSource.UTCNow; if (isPing)//ping just touches session above { return(new LockTransactionResult(transaction.ID, sapp.HostName, LockStatus.TransactionOK, LockErrorCause.Unspecified, null, appRunTimeSec, currentTrustLevel, null)); } var ns = m_Namespaces.GetOrRegister <object>(transaction.Namespace, (_) => new Namespace(App, transaction.Namespace), null); var ectx = new EvalContext(ss, ns, transaction); prepareTransaction(ectx); //prepare is not under the lock LockTransactionResult result; lock (ns) //execute is UNDER THE LOCK result = executeTransaction(ectx, appRunTimeSec, currentTrustLevel); return(result); } }
internal ServerLockSession(LockSessionData data) { Data = data; }