Exemplo n.º 1
0
        private void prepareTransaction(EvalContext ctx)
        {
            var statements = ctx.Transaction.Statements;

            for (var i = 0; i < statements.Length; i++)
            {
                var statement = statements[i];
                statement.Prepare(ctx, i.ToString() + ":/");
            }
        }
Exemplo n.º 2
0
        private string getDescr(string descr, EvalContext ctx)
        {
            if (descr.IsNullOrWhiteSpace())
            {
                descr = ctx.Transaction.Description;
            }

            if (descr.IsNullOrWhiteSpace())
            {
                descr = ctx.SessionDescription;
            }

            return(descr);
        }
Exemplo n.º 3
0
        //warning: this is called under the global lock on NS, do not block
        private LockTransactionResult executeTransaction(EvalContext ctx, uint appRunTimeSec, double trustLevel)
        {
            var status     = LockStatus.TransactionOK;
            var errorCause = LockErrorCause.Unspecified;

            var statements = ctx.Transaction.Statements;

            for (var i = 0; i < statements.Length; i++)
            {
                var statement = statements[i];
                statement.Execute(ctx);
                if (ctx.Aborted)
                {
                    status     = LockStatus.TransactionError;
                    errorCause = LockErrorCause.Statement;
                    break;
                }
            }

            //now Commit/Rollback all changes
            if (status == LockStatus.TransactionOK)
            {//commit
                foreach (var tbl in ctx.Namespace.m_MutatedTables)
                {
                    tbl.Commit(ctx.Session);
                }
            }
            else
            {//rollback
                foreach (var tbl in ctx.Namespace.m_MutatedTables)
                {
                    tbl.Rollback(ctx.Session);
                }
            }

            ctx.Namespace.m_MutatedTables.Clear();


            return(new LockTransactionResult(ctx.Transaction.ID,
                                             App.AsSky().HostName,
                                             status,
                                             errorCause,
                                             ctx.FailedStatement,
                                             appRunTimeSec,//passed-in not to calculate under lock
                                             trustLevel,
                                             ctx.Data));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns named variable value or value array created by this or another session.
        /// If not found then null is returned
        /// </summary>
        public object GetVariable(bool many, EvalContext ctx, string name, bool ignoreThisSession)
        {
            DataSlot slot;

            if (!m_Data.TryGetValue(name, out slot))
            {
                return(null);
            }

            var list = slot.Data;

            if (list == null)
            {
                return(null);
            }

            if (many)
            {
                Variable[] result;

                if (!ignoreThisSession)
                {
                    result = list.ToArray();
                }
                else
                {
                    result = list.Where(i => !i.SessionID.Equals(ctx.SessionID)).ToArray();
                }

                return(result.Length > 0 ? result : null);
            }
            //else Single
            if (list.Count == 0)
            {
                return(null);
            }
            if (!ignoreThisSession)
            {
                return(list[0]);
            }

            return(list.FirstOrDefault(i => !i.SessionID.Equals(ctx.SessionID)));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Returns true if named variable exists created by this or another session
        /// </summary>
        public bool Exists(EvalContext ctx, string name, object value, bool ignoreThisSession)
        {
            DataSlot slot;

            if (!m_Data.TryGetValue(name, out slot))
            {
                return(false);
            }

            var list = slot.Data;

            if (list == null)
            {
                return(false);
            }

            if (!ignoreThisSession)
            {
                if (value == null)
                {
                    return(list.Count > 0);
                }
                return(list.Any(e => e.Value != null && value.Equals(e.Value)));
            }

            for (var i = 0; i < list.Count; i++)
            {
                var var = list[i];
                if (!var.SessionID.Equals(ctx.SessionID))
                {
                    if (value == null)
                    {
                        return(true);
                    }
                    if (var.Value != null && var.Value.Equals(value))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Deletes named var, true if found and removed
        /// </summary>
        public bool DeleteVariable(EvalContext ctx, string name, object value)
        {
            DataSlot slot;

            if (!m_Data.TryGetValue(name, out slot))
            {
                return(false);
            }

            var list = slot.Data;

            if (list == null)
            {
                return(false);
            }

            var anymatch = list.Any(v => v.SessionID.Equals(ctx.SessionID) && (value == null || value.Equals(v.Value)));

            if (!anymatch)
            {
                return(false);
            }

            VarList newList = new VarList();

            for (var i = 0; i < list.Count; i++)
            {
                var var = list[i];
                if (var.SessionID.Equals(ctx.SessionID) && (value == null || value.Equals(var.Value)))
                {
                    continue;//skip what gets deleted
                }
                newList.Add(var);
            }
            slot.Change(newList);
            m_PendingChanges.Add(slot);
            m_Namespace.m_MutatedTables.Add(this);
            return(true);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Sets named var
        /// </summary>
        public bool SetVariable(EvalContext ctx, string name, object value, string description, DateTime?expirationTimeUTC, bool allowDuplicates)
        {
            DataSlot slot;
            VarList  list;

            if (!m_Data.TryGetValue(name, out slot))
            {
                slot = new DataSlot();
                list = new VarList();

                var var = new Variable(ctx.SessionID,
                                       ctx.Transaction.ID,
                                       App.TimeSource.UTCNow,
                                       expirationTimeUTC,
                                       getDescr(description, ctx),
                                       value);
                list.Add(var);
                slot.Change(list);

                m_Data.Add(name, slot);
                m_PendingChanges.Add(slot);
                m_Namespace.m_MutatedTables.Add(this);
                return(true);
            }

            list = slot.Data;

            if (list == null)
            {
                list = new VarList();

                var var = new Variable(ctx.SessionID,
                                       ctx.Transaction.ID,
                                       App.TimeSource.UTCNow,
                                       expirationTimeUTC,
                                       getDescr(description, ctx),
                                       value);
                list.Add(var);
                slot.Change(list);

                //20161102
                //m_Data.Add(name, slot);
                m_PendingChanges.Add(slot);
                m_Namespace.m_MutatedTables.Add(this);
                return(true);
            }

            if (list.Count > 0 && !allowDuplicates)
            {
                return(false);
            }

            var newList = new VarList(list);

            var replaced = false;

            for (var i = 0; i < newList.Count; i++)
            {
                var var = newList[i];
                if (var.SessionID.Equals(ctx.SessionID))
                {
                    var nvar = new Variable(ctx.SessionID,
                                            ctx.Transaction.ID,
                                            App.TimeSource.UTCNow,
                                            expirationTimeUTC,
                                            getDescr(description, ctx),
                                            value);
                    newList[i] = nvar;
                    replaced   = true;
                    break;
                }
            }

            if (!replaced)
            {
                var nvar = new Variable(ctx.SessionID,
                                        ctx.Transaction.ID,
                                        App.TimeSource.UTCNow,
                                        expirationTimeUTC,
                                        getDescr(description, ctx),
                                        value);
                newList.Add(nvar);
            }
            slot.Change(newList);
            m_PendingChanges.Add(slot);
            m_Namespace.m_MutatedTables.Add(this);
            return(true);
        }
Exemplo n.º 8
0
        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);
            }
        }