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; }
//--- 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; }
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; }
//--- 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); }
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; }
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; }
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; }
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); }
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); }
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; }
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; }
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; }
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; }
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 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; }
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; }
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; }
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; }