/// <summary> /// This .ctor is handy for message inspectors. /// Creates a substitute message for the original one with new value. /// Binding-specific context is cloned and headers/correlation data are cloned conditionaly /// </summary> public ResponseMsg(ResponseMsg inspectedOriginal, object newReturnValue, bool cloneHeaders = true, bool cloneCorrelation = true) : base() { m_RequestID = inspectedOriginal.m_RequestID; m_RemoteInstance = inspectedOriginal.m_RemoteInstance; m_ReturnValue = newReturnValue; CloneState(inspectedOriginal, cloneHeaders, cloneCorrelation); }
public void ClientDeliverAsyncResponse(ResponseMsg response) { }
public ResponseMsg ServerReturnResponse(ServerEndPoint endpoint, RequestMsg request, ResponseMsg response) { response.Headers.Add( new TextInfoHeader{ Text="Response generated at " + App.LocalizedTime.ToString(), Info = "Serve Node: " + endpoint.Node } ); return response; }
public ResponseMsg ClientDeliverResponse(CallSlot callSlot, ResponseMsg response) { if (response.ReturnValue is string) return new ResponseMsg(response, (string)(response.ReturnValue) + " Added by Client Inspector"); else return response; }
private void clientDeliverAsyncResponse(ResponseMsg response, bool first) { var callSlot = m_Calls.TryGetAndRemove(response.RequestID); if (callSlot!=null) callSlot.DeliverResponse(response); else { if (first) // If execution paused right after Send and before ClientDispatchedRequest could register callslot // we re-try asynchronously to find call slot again Task.Delay(1000).ContinueWith( (t, objRes) => clientDeliverAsyncResponse(objRes as ResponseMsg, false), response); else if (m_InstrumentationEnabled) Instrumentation.CallSlotNotFoundErrorEvent.Happened(); } }
public void ClientDeliverAsyncResponse(ResponseMsg response) { clientDeliverAsyncResponse(response, true); }
private ResponseMsg doWork(RequestMsg request) { var contract = request.Contract;//this throws when contract can't be found var server = getServerImplementer(request.ServerTransport.ServerEndpoint, contract);//throws when no implementor match found if (server.AuthenticationSupport) interpretAuthenticationHeader(request); //Authorizes user to the whole server contract and implementing class Security.Permission.AuthorizeAndGuardAction(server.Contract); Security.Permission.AuthorizeAndGuardAction(server.Implementation); serverImplementer.mapping mapped = server.SpecToMethodInfos(request.Method); Security.Permission.AuthorizeAndGuardAction(mapped.miContract); Security.Permission.AuthorizeAndGuardAction(mapped.miImplementation); Guid? checkedOutID; bool lockTaken; var instance = getServerInstance(server, request, out checkedOutID, out lockTaken); //throws when instance expired or cant be locked try { Guid? instanceID = null; bool isCtor = false; bool isDctor = false; if (server.InstanceMode == ServerInstanceMode.Stateful || server.InstanceMode == ServerInstanceMode.AutoConstructedStateful) { instanceID = request.RemoteInstance; isCtor = Attribute.IsDefined(mapped.miContract, typeof(ConstructorAttribute)); isDctor= Attribute.IsDefined(mapped.miContract, typeof(DestructorAttribute)); if (isCtor && isDctor) throw new ServerMethodInvocationException(StringConsts.GLUE_AMBIGUOUS_CTOR_DCTOR_DEFINITION_ERROR .Args( contract.FullName, request.MethodName)); if (server.InstanceMode != ServerInstanceMode.AutoConstructedStateful && !instanceID.HasValue && !isCtor) throw new ServerMethodInvocationException(StringConsts.GLUE_NO_SERVER_INSTANCE_ERROR .Args( contract.FullName, request.MethodName)); } //======================================================================================================== object result; try { var any = request as RequestAnyMsg; if (any!=null) result = mapped.miContract.Invoke(instance, any.Arguments); //do actual contract-implementing method work else { //call functor using typed RequestMsg derivative if (mapped.fBody==null) throw new ServerMethodInvocationException(StringConsts.GLUE_NO_ARGS_MARSHAL_LAMBDA_ERROR .Args( contract.FullName, request.MethodName)); result = mapped.fBody(instance, request); //do actual contract-implementing method work via Lambda } } catch(Exception bodyError) { Exception err = bodyError; if (err is TargetInvocationException)//unwrap the inner error which is wrapped by Invoke() if (err.InnerException!=null) err = err.InnerException; throw new ServerMethodInvocationException(StringConsts.GLUE_SERVER_CONTRACT_METHOD_INVOCATION_ERROR .Args(contract.FullName, request.MethodName, err.ToMessageWithType()), err); } //======================================================================================================== if (server.InstanceMode == ServerInstanceMode.Stateful || server.InstanceMode == ServerInstanceMode.AutoConstructedStateful) { if (isCtor || (server.InstanceMode == ServerInstanceMode.AutoConstructedStateful && !isDctor && !instanceID.HasValue)) { instanceID = Guid.NewGuid(); App.ObjectStore.CheckIn(instanceID.Value, instance, server.InstanceTimeoutMs); } else if (isDctor) { if (instanceID.HasValue) { App.ObjectStore.Delete(instanceID.Value); instanceID = null; checkedOutID = null; } } } if (request.OneWay) return null; var response = new ResponseMsg(request.RequestID, instanceID, result); response.__SetBindingSpecificContext(request); return response; } finally { if (lockTaken) Monitor.Exit(instance); if (checkedOutID.HasValue) App.ObjectStore.CheckIn(checkedOutID.Value, server.InstanceTimeoutMs); } }
private ResponseMsg handleRequest(RequestMsg request) { try { ServerCallContext.__SetThreadLevelContext(request); try { var response = doWork(request); var rhdr = ServerCallContext.GetResponseHeadersOrNull(); if (rhdr!=null && response!=null) response.Headers = rhdr; return response; } finally { ServerCallContext.__ResetThreadLevelContext(); } } catch(Exception error) { if (request.OneWay) { //because it is one-way, the caller will never know about it this.WriteLog(LogSrc.Server, MessageType.Error, string.Format(StringConsts.GLUE_SERVER_ONE_WAY_CALL_ERROR + error.ToMessageWithType()), from: "SrvrHndlr.handleRequest(ReqMsg)", exception: error ); return null; } else { var red = new RemoteExceptionData(error); var response = new ResponseMsg(request.RequestID, red); response.__SetBindingSpecificContext(request); return response; } } }
/// <summary> /// Handles request synchronously in the context of the calling thread. Returns NULL for one-way calls /// </summary> public ResponseMsg HandleRequestFailure(FID reqID, bool oneWay, Exception failure, object bindingSpecCtx) { if (oneWay) return null; var red = new RemoteExceptionData(failure); var response = new ResponseMsg(reqID, red); response.__SetBindingSpecificContext(bindingSpecCtx); return response; }