Ejemplo n.º 1
0
 private Yield Epilogue(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     _log.Debug("in epilogue");
     if (request.IsSuccessful && "disposal".EqualsInvariant(context.Feature.Signature) && context.IsTaskEnvDisposed)
     {
         throw new Exception("context disposed in epilogue");
     }
     if ("prologueepilogue".EqualsInvariant(context.Feature.Signature))
     {
         _log.DebugFormat("checking prologue data for epilogue in Env #{0}", TaskEnv.Current.GetHashCode());
         if (string.IsNullOrEmpty(PrologueData))
         {
             throw new Exception("no prologue data in slot");
         }
         if (PrologueData != context.GetState <string>("prologue"))
         {
             throw new Exception("state from prologue didn't make it to epilogue");
         }
     }
     else if ("epilogue".EqualsInvariant(context.Feature.Signature))
     {
         _log.DebugFormat("checking epilogue data for epilogue in Env #{0}", TaskEnv.Current.GetHashCode());
         if (string.IsNullOrEmpty(EpilogueData))
         {
             throw new Exception("no epilogue data in slot");
         }
         if (EpilogueData != context.GetState <string>("epilogue"))
         {
             throw new Exception("state from feature didn't make it to epilogue");
         }
     }
     response.Return(request);
     yield break;
 }
Ejemplo n.º 2
0
 //--- Class Methods ---
 public static DekiContext GetContext(DreamContext dreamContext) {
     var context = dreamContext.GetState<DekiContext>();
     if(context == null) {
         throw new DekiContextAccessException("DekiContext.Current is not set, because the current DreamContext does not contain a reference");
     }
     return context;
 }
Ejemplo n.º 3
0
            public Yield Spawn(DreamContext context, DreamMessage request, Result <DreamMessage> response)
            {
                var guid = Guid.NewGuid();

                ContextVar = new ContextLifeSpan(guid);
                context.SetState(guid);
                context.SetState(ContextVar);
                ContextLifeSpan capturedInner = null;

                yield return(Async.Fork(() =>
                {
                    var innerContextVar = DreamContext.Current.GetState <ContextLifeSpan>();
                    capturedInner = innerContextVar;
                    if (innerContextVar == ContextVar)
                    {
                        throw new Exception("spawned context instances were same");
                    }
                    if (innerContextVar.Guid != guid)
                    {
                        throw new Exception("spawned context guid is wrong");
                    }
                    if (innerContextVar.IsDisposed)
                    {
                        throw new Exception("subcall: context is disposed");
                    }
                }, new Result()));

                var contextVar = context.GetState <ContextLifeSpan>();

                if (contextVar == null)
                {
                    throw new Exception("context instance is gone");
                }
                if (capturedInner == contextVar)
                {
                    throw new Exception("outer instance was changed to inner");
                }
                if (!capturedInner.IsDisposed)
                {
                    throw new Exception("inner instance wasn't disposed after closure completion");
                }
                if (contextVar.Guid != guid)
                {
                    throw new Exception("context guid is wrong");
                }
                if (contextVar != ContextVar)
                {
                    throw new Exception("context instance changed");
                }
                if (contextVar.IsDisposed)
                {
                    throw new Exception("context is disposed");
                }
                response.Return(DreamMessage.Ok());
                yield break;
            }
Ejemplo n.º 4
0
        //--- Class Methods ---
        public static DekiContext GetContext(DreamContext dreamContext)
        {
            var context = dreamContext.GetState <DekiContext>();

            if (context == null)
            {
                throw new DekiContextAccessException("DekiContext.Current is not set, because the current DreamContext does not contain a reference");
            }
            return(context);
        }
Ejemplo n.º 5
0
 public Yield CheckPrologue(DreamContext context, DreamMessage request, Result <DreamMessage> response)
 {
     _log.DebugFormat("checking prologue data in Env #{0}", TaskEnv.Current.GetHashCode());
     if (string.IsNullOrEmpty(PrologueData))
     {
         throw new Exception("no prologue data in slot");
     }
     if (PrologueData != context.GetState <string>("prologue"))
     {
         throw new Exception("state from prologue didn't make it to feature");
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
Ejemplo n.º 6
0
            public Yield CallCoroutine(DreamContext context, DreamMessage request, Result <DreamMessage> response)
            {
                _log.Debug("callcoroutine start");
                var guid = Guid.NewGuid();

                ContextVar = new ContextLifeSpan(guid);
                context.SetState(guid);
                context.SetState(ContextVar);
                if (context.GetState <ContextLifeSpan>() == null)
                {
                    throw new Exception("context instance was never set");
                }
                _log.DebugFormat("callcoroutine calling coroutine within Env #{0}", TaskEnv.Current.GetHashCode());
                yield return(Coroutine.Invoke(SubCall, new Result()));

                var contextVar = context.GetState <ContextLifeSpan>();

                _log.DebugFormat("callcoroutine coroutine returned within Env #{0}", TaskEnv.Current.GetHashCode());
                if (contextVar == null)
                {
                    throw new Exception("context instance is gone");
                }
                if (contextVar.Guid != guid)
                {
                    throw new Exception("context guid is wrong");
                }
                if (contextVar != ContextVar)
                {
                    throw new Exception("context instance changed");
                }
                if (contextVar.IsDisposed)
                {
                    throw new Exception("context is disposed");
                }
                response.Return(DreamMessage.Ok());
                yield break;
            }
Ejemplo n.º 7
0
            public Yield CalledPlug(DreamContext context, DreamMessage request, Result <DreamMessage> response)
            {
                _log.Debug("calledplug start");
                var contextVar = context.GetState <ContextLifeSpan>();

                if (contextVar != null)
                {
                    throw new Exception("called plug context instance already exists");
                }
                context.SetState(new ContextLifeSpan(Guid.NewGuid()));
                _log.Debug("calledplug return");
                response.Return(DreamMessage.Ok());
                _log.Debug("calledplug end");
                yield break;
            }
Ejemplo n.º 8
0
            public Yield CallPlug(DreamContext context, DreamMessage request, Result <DreamMessage> response)
            {
                _log.Debug("callplug start");
                var guid = Guid.NewGuid();

                ContextVar = new ContextLifeSpan(guid);
                context.SetState(guid);
                _log.Debug("setting disposable state");
                context.SetState(ContextVar);
                Result <DreamMessage> sub;

                _log.Debug("calling plug");
                yield return(sub = Self.At("calledplug").GetAsync());

                _log.Debug("return from plug");
                if (!sub.Value.IsSuccessful)
                {
                    response.Return(sub.Value);
                }
                var contextVar = context.GetState <ContextLifeSpan>();

                if (contextVar == null)
                {
                    throw new Exception("context instance is gone");
                }
                if (contextVar.Guid != guid)
                {
                    throw new Exception("context guid is wrong");
                }
                if (contextVar != ContextVar)
                {
                    throw new Exception("context instance changed");
                }
                if (contextVar.IsDisposed)
                {
                    throw new Exception("context is disposed");
                }
                _log.Debug("callplug return");
                response.Return(DreamMessage.Ok());
                _log.Debug("callplug end");
                yield break;
            }
        public static XDoc WebLink(
            [DekiScriptParam("link uri")] string uri,
            [DekiScriptParam("link contents; can be text, an image, or another document (default: link uri)", true)] object text,
            [DekiScriptParam("link hover title (default: none)", true)] string title,
            [DekiScriptParam("link target (default: none)", true)] string target
            )
        {
            // check __settings.nofollow if links should be followed or not
            bool         nofollow = true;
            DreamContext context  = DreamContext.CurrentOrNull;

            if (context != null)
            {
                DekiScriptEnv env = context.GetState <DekiScriptEnv>();
                if (env != null)
                {
                    // TODO (steveb): this should be stored in the runtime instead!
                    DekiScriptBool setting = env.Vars.GetAt(new[] { DekiScriptEnv.SETTINGS, "nofollow" }) as DekiScriptBool;
                    if (setting != null)
                    {
                        nofollow = setting.AsBool() ?? true;
                    }
                }
            }

            XDoc result = DekiScriptLiteral.FromNativeValue(text ?? uri).AsEmbeddableXml(true);
            XDoc body   = result["body[not(@target)]"];

            result.Start("body").Start("a");
            if (nofollow)
            {
                result.Attr("rel", "custom nofollow");
            }
            else
            {
                result.Attr("rel", "custom");
            }
            result.Attr("href", WebCheckUri(uri)).Attr("title", title).Attr("target", target).AddNodes(body).End().End();
            body.Remove();
            return(result);
        }
Ejemplo n.º 10
0
 private DreamMessage ExceptionTranslation(DreamContext context, Exception exception)
 {
     if (exception is CustomException)
     {
         _log.DebugFormat("caught custom exception");
         if (context.IsTaskEnvDisposed)
         {
             return(DreamMessage.BadRequest("context is disposed"));
         }
         if (ContextVar == null)
         {
             return(DreamMessage.BadRequest("context var wasn't set"));
         }
         if (ContextVar != context.GetState <ContextLifeSpan>())
         {
             return(DreamMessage.BadRequest("context vars didn't match"));
         }
         return(DreamMessage.Ok());
     }
     return(null);
 }
Ejemplo n.º 11
0
 public Yield Spawn(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     var guid = Guid.NewGuid();
     ContextVar = new ContextLifeSpan(guid);
     context.SetState(guid);
     context.SetState(ContextVar);
     ContextLifeSpan capturedInner = null;
     yield return Async.Fork(() =>
     {
         var innerContextVar = DreamContext.Current.GetState<ContextLifeSpan>();
         capturedInner = innerContextVar;
         if(innerContextVar == ContextVar) {
             throw new Exception("spawned context instances were same");
         }
         if(innerContextVar.Guid != guid) {
             throw new Exception("spawned context guid is wrong");
         }
         if(innerContextVar.IsDisposed) {
             throw new Exception("subcall: context is disposed");
         }
     }, new Result());
     var contextVar = context.GetState<ContextLifeSpan>();
     if(contextVar == null) {
         throw new Exception("context instance is gone");
     }
     if(capturedInner == contextVar) {
         throw new Exception("outer instance was changed to inner");
     }
     if(!capturedInner.IsDisposed) {
         throw new Exception("inner instance wasn't disposed after closure completion");
     }
     if(contextVar.Guid != guid) {
         throw new Exception("context guid is wrong");
     }
     if(contextVar != ContextVar) {
         throw new Exception("context instance changed");
     }
     if(contextVar.IsDisposed) {
         throw new Exception("context is disposed");
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
Ejemplo n.º 12
0
        private Yield EpilogueStats(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            // check if we need to skip this feature
            if (context.Feature.PathSegments.Length > 1 && context.Feature.PathSegments[context.Feature.ServiceUri.Segments.Length].StartsWith("@"))
            {
                response.Return(request);
                yield break;
            }

            // check if the epilogue was called without a deki instance (e.g. during initialization or with an invalid hostname)
            if (DekiContext.CurrentOrNull == null || !DekiContext.Current.HasInstance)
            {
                response.Return(request);
                yield break;
            }

            // compute execution time
            TimeSpan executionTime = TimeSpan.Zero;

            System.Diagnostics.Stopwatch elapsedTimeSw = context.GetState <System.Diagnostics.Stopwatch>("stats-stopwatch");
            if (elapsedTimeSw != null)
            {
                elapsedTimeSw.Stop();
                executionTime = TimeSpan.FromMilliseconds(elapsedTimeSw.ElapsedMilliseconds);
            }

            // increate instance hit counter
            DekiContext.Current.Instance.IncreasetHitCounter(request.IsSuccessful, executionTime);

            // if logging is enabled, grab the response text if the request was not successful
            string exception      = string.Empty;
            XDoc   activeConfig   = DekiContext.Current.Instance.Config ?? Config;
            bool   loggingEnabled = !String.IsNullOrEmpty(activeConfig["dblogging-conn-string"].AsText);

            if (loggingEnabled)
            {
                if (!request.IsSuccessful)
                {
                    exception = request.AsText();
                }
            }

            //Build overall request stats header
            StringBuilder statsHeaderSb = new StringBuilder();

            statsHeaderSb.AppendFormat("{0}={1}; ", "request-time-ms", (int)executionTime.TotalMilliseconds);

            //Append data stats
            IDekiDataStats sessionStats = DbUtils.CurrentSession as IDekiDataStats;
            Dictionary <string, string> stats;

            if (sessionStats != null)
            {
                stats = sessionStats.GetStats();
                if (stats != null)
                {
                    foreach (KeyValuePair <string, string> kvp in stats)
                    {
                        statsHeaderSb.AppendFormat("{0}={1}; ", kvp.Key, kvp.Value);
                    }
                }
            }

            //Append context stats
            stats = DekiContext.Current.Stats;
            if (stats.Count > 0)
            {
                foreach (KeyValuePair <string, string> kvp in stats)
                {
                    statsHeaderSb.AppendFormat("{0}={1}; ", kvp.Key, kvp.Value);
                }
            }

            string requestStats = statsHeaderSb.ToString();

            request.Headers.Add(DATA_STATS_HEADERNAME, requestStats);
            DekiContext.Current.Instance.Log.InfoFormat("Finished [{0}:{1}] [{2}] {3}", context.Verb, context.Uri.Path, request.Status.ToString(), requestStats);


            // check if there is a catalog to record per-request information
            if (loggingEnabled)
            {
                try {
                    //Write request/response info to stats table after sending response back to client
                    UserBE u        = DekiContext.Current.User;
                    string username = u == null ? string.Empty : u.Name;
                    DbUtils.CurrentSession.RequestLog_Insert(context.Uri, context.Verb, DekiContext.Current.RequestHost, context.Request.Headers.DreamOrigin, DekiContext.Current.Instance.Id, context.Feature.Signature, request.Status, username, (uint)executionTime.TotalMilliseconds, exception);
                } catch (Exception x) {
                    DekiContext.Current.Instance.Log.Error(string.Format("Failed to write request to db log. [Instance:{0}; Feature:{1}; Verb:{2}; Status:{3}; Duration:{4};]", DekiContext.Current.Instance.Id, context.Feature.Signature, context.Verb, (int)request.Status, executionTime), x);
                }
            }

            // continue processing
            response.Return(request);
            yield break;
        }
Ejemplo n.º 13
0
 public Yield CallCoroutine(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("callcoroutine start");
     var guid = Guid.NewGuid();
     ContextVar = new ContextLifeSpan(guid);
     context.SetState(guid);
     context.SetState(ContextVar);
     if(context.GetState<ContextLifeSpan>() == null) {
         throw new Exception("context instance was never set");
     }
     _log.DebugFormat("callcoroutine calling coroutine within Env #{0}", TaskEnv.Current.GetHashCode());
     yield return Coroutine.Invoke(SubCall, new Result());
     var contextVar = context.GetState<ContextLifeSpan>();
     _log.DebugFormat("callcoroutine coroutine returned within Env #{0}", TaskEnv.Current.GetHashCode());
     if(contextVar == null) {
         throw new Exception("context instance is gone");
     }
     if(contextVar.Guid != guid) {
         throw new Exception("context guid is wrong");
     }
     if(contextVar != ContextVar) {
         throw new Exception("context instance changed");
     }
     if(contextVar.IsDisposed) {
         throw new Exception("context is disposed");
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
Ejemplo n.º 14
0
 public Yield CalledPlug(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("calledplug start");
     var contextVar = context.GetState<ContextLifeSpan>();
     if(contextVar != null) {
         throw new Exception("called plug context instance already exists");
     }
     context.SetState(new ContextLifeSpan(Guid.NewGuid()));
     _log.Debug("calledplug return");
     response.Return(DreamMessage.Ok());
     _log.Debug("calledplug end");
     yield break;
 }
Ejemplo n.º 15
0
 public Yield CallPlug(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("callplug start");
     var guid = Guid.NewGuid();
     ContextVar = new ContextLifeSpan(guid);
     context.SetState(guid);
     _log.Debug("setting disposable state");
     context.SetState(ContextVar);
     Result<DreamMessage> sub;
     _log.Debug("calling plug");
     yield return sub = Self.At("calledplug").GetAsync();
     _log.Debug("return from plug");
     if(!sub.Value.IsSuccessful) {
         response.Return(sub.Value);
     }
     var contextVar = context.GetState<ContextLifeSpan>();
     if(contextVar == null) {
         throw new Exception("context instance is gone");
     }
     if(contextVar.Guid != guid) {
         throw new Exception("context guid is wrong");
     }
     if(contextVar != ContextVar) {
         throw new Exception("context instance changed");
     }
     if(contextVar.IsDisposed) {
         throw new Exception("context is disposed");
     }
     _log.Debug("callplug return");
     response.Return(DreamMessage.Ok());
     _log.Debug("callplug end");
     yield break;
 }
Ejemplo n.º 16
0
 public Yield CheckPrologue(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.DebugFormat("checking prologue data in Env #{0}", TaskEnv.Current.GetHashCode());
     if(string.IsNullOrEmpty(PrologueData)) {
         throw new Exception("no prologue data in slot");
     }
     if(PrologueData != context.GetState<string>("prologue")) {
         throw new Exception("state from prologue didn't make it to feature");
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
Ejemplo n.º 17
0
 private DreamMessage ExceptionTranslation(DreamContext context, Exception exception)
 {
     if(exception is CustomException) {
         _log.DebugFormat("caught custom exception");
         if(context.IsTaskEnvDisposed) {
             return DreamMessage.BadRequest("context is disposed");
         }
         if(ContextVar == null) {
             return DreamMessage.BadRequest("context var wasn't set");
         }
         if(ContextVar != context.GetState<ContextLifeSpan>()) {
             return DreamMessage.BadRequest("context vars didn't match");
         }
         return DreamMessage.Ok();
     }
     return null;
 }
Ejemplo n.º 18
0
 private Yield Epilogue(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     _log.Debug("in epilogue");
     if(request.IsSuccessful && "disposal".EqualsInvariant(context.Feature.Signature) && context.IsTaskEnvDisposed) {
         throw new Exception("context disposed in epilogue");
     }
     if("prologueepilogue".EqualsInvariant(context.Feature.Signature)) {
         _log.DebugFormat("checking prologue data for epilogue in Env #{0}", TaskEnv.Current.GetHashCode());
         if(string.IsNullOrEmpty(PrologueData)) {
             throw new Exception("no prologue data in slot");
         }
         if(PrologueData != context.GetState<string>("prologue")) {
             throw new Exception("state from prologue didn't make it to epilogue");
         }
     } else if("epilogue".EqualsInvariant(context.Feature.Signature)) {
         _log.DebugFormat("checking epilogue data for epilogue in Env #{0}", TaskEnv.Current.GetHashCode());
         if(string.IsNullOrEmpty(EpilogueData)) {
             throw new Exception("no epilogue data in slot");
         }
         if(EpilogueData != context.GetState<string>("epilogue")) {
             throw new Exception("state from feature didn't make it to epilogue");
         }
     }
     response.Return(request);
     yield break;
 }
Ejemplo n.º 19
0
 private Yield EpilogueStats(DreamContext context, DreamMessage request, Result<DreamMessage> response) {
     var sw = context.GetState<Stopwatch>("stats-stopwatch");
     sw.Stop();
     _log.InfoFormat("Finished [{0}:{1}] [{2}] {3:0}ms", context.Verb, context.Uri.Path, request.Status.ToString(), sw.ElapsedMilliseconds);
     response.Return(request);
     yield break;
 }