/// <summary> /// Maps the interfaces of the provided <paramref name="implementationType"/>. /// </summary> /// <param name="implementationType">The implementation type.</param> /// <param name="invoker">The grain method invoker.</param> /// <returns>The mapped interface.</returns> private static Dictionary<int, InterceptedMethodInvoker> CreateInterfaceToImplementationMap( Type implementationType, IGrainMethodInvoker invoker) { if (implementationType.IsConstructedGenericType) return CreateMapForConstructedGeneric(implementationType, invoker); return CreateMapForNonGeneric(implementationType, invoker); }
internal LocalObjectData(IAddressable obj, GuidId observerId, IGrainMethodInvoker invoker) { LocalObject = new WeakReference(obj); ObserverId = observerId; Invoker = invoker; Messages = new Queue <Message>(); Running = false; }
public GrainReference CreateObjectReference(IAddressable obj, IGrainMethodInvoker invoker) { if (RuntimeContext.Current == null) { return(this.HostedClient.CreateObjectReference(obj, invoker)); } throw new InvalidOperationException("Cannot create a local object reference from a grain."); }
internal LocalObjectData(IAddressable obj, GrainId grain, IGrainMethodInvoker invoker) { LocalObject = new WeakReference(obj); Grain = grain; Invoker = invoker; Messages = new Queue <Message>(); Running = false; }
public async static System.Threading.Tasks.Task <IClientObserver> CreateObjectReference(IClientObserver obj) { if (methodInvoker == null) { methodInvoker = new ClientObserverMethodInvoker(); } return(ClientObserverFactory.Cast(await GrainReference.CreateObjectReference(obj, methodInvoker))); }
internal LocalObjectData(IAddressable obj, ObserverGrainId observerId, IGrainMethodInvoker invoker) { this.LocalObject = new WeakReference(obj); this.ObserverId = observerId; this.Invoker = invoker; this.Messages = new Queue <Message>(); this.Running = false; }
internal bool TryAddExtension(IGrainExtensionMethodInvoker invoker, IGrainExtension extension) { this.lastInvoker = null; if (extensionInvoker == null) { extensionInvoker = new ExtensionInvoker(); } return(extensionInvoker.TryAddExtension(invoker, extension)); }
/// <summary> /// Maps the interfaces of the provided <paramref name="implementationType"/>. /// </summary> /// <param name="implementationType">The implementation type.</param> /// <param name="invoker">The grain method invoker.</param> /// <returns>The mapped interface.</returns> private static Dictionary <int, InterceptedMethodInvoker> CreateInterfaceToImplementationMap( Type implementationType, IGrainMethodInvoker invoker) { if (implementationType.IsConstructedGenericType) { return(CreateMapForConstructedGeneric(implementationType, invoker)); } return(CreateMapForNonGeneric(implementationType, invoker)); }
public IGrainMethodInvoker GetInvoker(GrainTypeManager typeManager, int interfaceId, string genericGrainType = null) { if (lastInvoker != null && interfaceId == lastInvoker.InterfaceId) return lastInvoker; var invoker = typeManager.GetInvoker(interfaceId); lastInvoker = invoker; return lastInvoker; }
/// <summary> /// Initializes a new instance of the <see cref="GrainMethodInvoker"/> class. /// </summary> /// <param name="grain">The grain.</param> /// <param name="request">The request.</param> /// <param name="rootInvoker">The generated invoker.</param> /// <param name="filters">The invocation interceptors.</param> /// <param name="interfaceToImplementationMapping">The implementation map.</param> public GrainMethodInvoker( IAddressable grain, InvokeMethodRequest request, IGrainMethodInvoker rootInvoker, List <IIncomingGrainCallFilter> filters, InterfaceToImplementationMappingCache interfaceToImplementationMapping) { this.request = request; this.rootInvoker = rootInvoker; this.Grain = grain; this.filters = filters; this.interfaceToImplementationMapping = interfaceToImplementationMapping; }
public IGrainMethodInvoker GetInvoker(GrainTypeManager typeManager, int interfaceId, string genericGrainType = null) { if (lastInvoker != null && interfaceId == lastInvoker.InterfaceId) { return(lastInvoker); } var invoker = typeManager.GetInvoker(interfaceId); lastInvoker = invoker; return(lastInvoker); }
public async Task<object> Invoke(MethodInfo methodInfo, InvokeMethodRequest request, IGrainMethodInvoker invoker) { var initialLastStreamValue = this.lastStreamValue; var result = await invoker.Invoke(this, request); // If the last stream value changed after the invoke, then the stream must have produced a value, double // it for testing purposes. if (this.lastStreamValue != initialLastStreamValue) { this.lastStreamValue *= 2; } return result; }
internal void RemoveExtension(IGrainExtension extension) { this.lastInvoker = null; if (extensionInvoker != null) { if (extensionInvoker.Remove(extension)) { extensionInvoker = null; } } else { throw new InvalidOperationException("Grain extensions not installed."); } }
public GrainReference CreateObjectReference(IAddressable obj, IGrainMethodInvoker invoker) { if (obj is GrainReference) { throw new ArgumentException("Argument obj is already a grain reference."); } GrainReference gr = GrainReference.NewObserverGrainReference(clientId, GuidId.GetNewGuidId()); if (!localObjects.TryAdd(gr.ObserverId, new LocalObjectData(obj, gr.ObserverId, invoker))) { throw new ArgumentException(String.Format("Failed to add new observer {0} to localObjects collection.", gr), "gr"); } return(gr); }
public async Task <GrainReference> CreateObjectReference(IAddressable obj, IGrainMethodInvoker invoker) { if (obj is GrainReference) { throw new ArgumentException("Argument obj is already a grain reference."); } GrainId target = GrainId.NewClientAddressableGrainId(); await transport.RegisterObserver(target); lock (localObjects) { localObjects.Add(target, new LocalObjectData(obj, target, invoker)); } return(GrainReference.FromGrainId(target)); }
/// <summary> /// Returns a grain method invoker which calls the grain's implementation of <see cref="IGrainInvokeInterceptor"/> /// if it exists, otherwise calling the provided <paramref name="invoker"/> directly. /// </summary> /// <param name="implementationType">The grain type.</param> /// <param name="interfaceId">The interface id.</param> /// <param name="invoker"> /// The underlying invoker, which will be passed to the grain's <see cref="IGrainInvokeInterceptor.Invoke"/> /// method. /// </param> /// <returns> /// A grain method invoker which calls the grain's implementation of <see cref="IGrainInvokeInterceptor"/>. /// </returns> public InterceptedMethodInvoker GetOrCreate(Type implementationType, int interfaceId, IGrainMethodInvoker invoker) { var implementation = invokers.GetOrAdd( implementationType, _ => new ConcurrentDictionary<int, InterceptedMethodInvoker>()); InterceptedMethodInvoker interceptedMethodInvoker; if (implementation.TryGetValue(interfaceId, out interceptedMethodInvoker)) { return interceptedMethodInvoker; } // Create a mapping between the interface and the implementation. return implementation.GetOrAdd( interfaceId, _ => CreateInterceptedMethodInvoker(implementationType, interfaceId, invoker)); }
/// <summary> /// Creates and returns a map from interface id to intercepted invoker for non-generic or open-generic types. /// </summary> /// <param name="implementationType">The implementation type.</param> /// <param name="invoker">The underlying invoker.</param> /// <returns>A map from interface id to intercepted invoker.</returns> private static Dictionary<int, InterceptedMethodInvoker> CreateMapForNonGeneric(Type implementationType, IGrainMethodInvoker invoker) { if (implementationType.IsConstructedGenericType) { throw new InvalidOperationException( $"Type {implementationType} passed to {nameof(CreateMapForNonGeneric)} is a constructed generic type."); } var implementationTypeInfo = implementationType.GetTypeInfo(); var interfaces = implementationType.GetInterfaces(); // Create an invoker for every interface on the provided type. var result = new Dictionary<int, InterceptedMethodInvoker>(interfaces.Length); foreach (var iface in interfaces) { var methods = GrainInterfaceUtils.GetMethods(iface); // Map every method on this interface from the definition interface onto the implementation class. var methodMap = new Dictionary<int, MethodInfo>(methods.Length); var mapping = default(InterfaceMapping); foreach (var method in methods) { // If this method is not from the expected interface (eg, because it's from a parent interface), then // get the mapping for the interface which it does belong to. if (mapping.InterfaceType != method.DeclaringType) { mapping = implementationTypeInfo.GetRuntimeInterfaceMap(method.DeclaringType); } // Find the index of the interface method and then get the implementation method at that position. for (var k = 0; k < mapping.InterfaceMethods.Length; k++) { if (mapping.InterfaceMethods[k] != method) continue; methodMap[GrainInterfaceUtils.ComputeMethodId(method)] = mapping.TargetMethods[k]; break; } } // Add the resulting map of methodId -> method to the interface map. var interfaceId = GrainInterfaceUtils.GetGrainInterfaceId(iface); result[interfaceId] = new InterceptedMethodInvoker(invoker, methodMap); } return result; }
/// <inheritdoc /> public GrainReference CreateObjectReference(IAddressable obj, IGrainMethodInvoker invoker) { if (obj is GrainReference) { throw new ArgumentException("Argument obj is already a grain reference."); } var grainReference = GrainReference.NewObserverGrainReference(this.ClientAddress.Grain, GuidId.GetNewGuidId(), this.grainReferenceRuntime); if (!this.invokableObjects.TryRegister(obj, grainReference.ObserverId, invoker)) { throw new ArgumentException( string.Format("Failed to add new observer {0} to localObjects collection.", grainReference), nameof(grainReference)); } return(grainReference); }
public OrleansRequesterMiddleware(OcelotRequestDelegate next, IClusterClientBuilder clusterClientBuilder, IGrainReference grainReference, IGrainMethodInvoker grainInvoker, IRouteValuesBuilder routeValuesBuilder, IOptions <OrleansRequesterConfiguration> config, IOrleansAuthorisation authorisation, IOcelotLoggerFactory loggerFactory) : base(loggerFactory.CreateLogger <OrleansRequesterMiddleware>()) { this._clusterClientBuilder = clusterClientBuilder; this._grainReference = grainReference; this._grainInvoker = grainInvoker; this._routeValuesBuilder = routeValuesBuilder; this._logger = loggerFactory.CreateLogger <OrleansRequesterMiddleware>(); this._config = config?.Value; this._authorisation = authorisation; this._next = next; }
public IGrainMethodInvoker GetInvoker(string genericGrainType = null) { if (String.IsNullOrEmpty(genericGrainType)) { return(invoker ?? (invoker = (IGrainMethodInvoker)Activator.CreateInstance(baseInvokerType))); } if (cachedGenericInvokers.ContainsKey(genericGrainType)) { return(cachedGenericInvokers[genericGrainType]); } var typeArgs = TypeUtils.GenericTypeArgs(genericGrainType); var concreteType = baseInvokerType.MakeGenericType(typeArgs); var inv = (IGrainMethodInvoker)Activator.CreateInstance(concreteType); cachedGenericInvokers[genericGrainType] = inv; return(inv); }
// capture stats async Task<object> InvokeInterceptor(MethodInfo targetMethod, InvokeMethodRequest request, IGrain grain, IGrainMethodInvoker invoker) { // round down to nearest 10 seconds to group results var grainName = grain.GetType().FullName; var stopwatch = Stopwatch.StartNew(); // invoke grain object result = null; if (this.innerInterceptor != null) { result = await this.innerInterceptor(targetMethod, request, grain, invoker); } else { result = await invoker.Invoke(grain, request); } stopwatch.Stop(); var elapsedMs = (double)stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond; var key = $"{grainName}.{targetMethod?.Name ?? "Unknown"}"; grainTrace.AddOrUpdate(key, _ => { return new GrainTraceEntry { Count = 1, SiloAddress = siloAddress, ElapsedTime = elapsedMs, Grain = grainName, Method = targetMethod?.Name ?? "Unknown", Period = DateTime.UtcNow }; }, (_, last) => { last.Count += 1; last.ElapsedTime += elapsedMs; return last; }); return result; }
/// <summary> /// Returns a new <see cref="InterceptedMethodInvoker"/> for the provided values. /// </summary> /// <param name="implementationType">The grain type.</param> /// <param name="interfaceId">The interface id.</param> /// <param name="invoker">The invoker.</param> /// <returns>A new <see cref="InterceptedMethodInvoker"/> for the provided values.</returns> private static InterceptedMethodInvoker CreateInterceptedMethodInvoker( Type implementationType, int interfaceId, IGrainMethodInvoker invoker) { // If a grain extension is being invoked, the implementation map must match the methods on the extension // and not the grain implementation. var extensionMap = invoker as IGrainExtensionMap; if (extensionMap != null) { IGrainExtension extension; if (extensionMap.TryGetExtension(interfaceId, out extension)) { implementationType = extension.GetType(); } } var implementationMap = GetInterfaceToImplementationMap(interfaceId, implementationType); return new InterceptedMethodInvoker(invoker, implementationMap); }
/// <summary> /// Returns a grain method invoker which calls the grain's implementation of <see cref="IGrainInvokeInterceptor"/> /// if it exists, otherwise calling the provided <paramref name="invoker"/> directly. /// </summary> /// <param name="implementationType">The grain type.</param> /// <param name="interfaceId">The interface id.</param> /// <param name="invoker"> /// The underlying invoker, which will be passed to the grain's <see cref="IGrainInvokeInterceptor.Invoke"/> /// method. /// </param> /// <returns> /// A grain method invoker which calls the grain's implementation of <see cref="IGrainInvokeInterceptor"/>. /// </returns> public InterceptedMethodInvoker GetOrCreate(Type implementationType, int interfaceId, IGrainMethodInvoker invoker) { // Get or create the mapping between interfaceId and invoker for the provided type. Dictionary<int, InterceptedMethodInvoker> invokerMap; if (!this.invokers.TryGetValue(implementationType, out invokerMap)) { // Generate an the invoker mapping using the provided invoker. this.invokers[implementationType] = invokerMap = CreateInterfaceToImplementationMap(implementationType, invoker); } // Attempt to get the invoker for the provided interfaceId. InterceptedMethodInvoker interceptedMethodInvoker; if (!invokerMap.TryGetValue(interfaceId, out interceptedMethodInvoker)) { throw new InvalidOperationException( $"Type {implementationType} does not implement interface with id {interfaceId} ({interfaceId:X})."); } return interceptedMethodInvoker; }
public GrainReference CreateObjectReference(IAddressable obj, IGrainMethodInvoker invoker) { if (obj is GrainReference) { throw new ArgumentException("Argument obj is already a grain reference.", nameof(obj)); } if (obj is Grain) { throw new ArgumentException("Argument must not be a grain class.", nameof(obj)); } GrainReference gr = GrainReference.NewObserverGrainReference(clientId, GuidId.GetNewGuidId(), this.GrainReferenceRuntime); if (!localObjects.TryRegister(obj, gr.ObserverId, invoker)) { throw new ArgumentException(String.Format("Failed to add new observer {0} to localObjects collection.", gr), "gr"); } return(gr); }
public IGrainMethodInvoker GetInvoker(int interfaceId, string genericGrainType = null) { // Return previous cached invoker, if applicable if (lastInvoker != null && interfaceId == lastInvoker.InterfaceId) // extension invoker returns InterfaceId==0, so this condition will never be true if an extension is installed { return(lastInvoker); } if (extensionInvoker != null && extensionInvoker.IsExtensionInstalled(interfaceId)) // HasExtensionInstalled(interfaceId) // Shared invoker for all extensions installed on this grain { lastInvoker = extensionInvoker; } else { // Find the specific invoker for this interface / grain type lastInvoker = RuntimeClient.Current.GetInvoker(interfaceId, genericGrainType); } return(lastInvoker); }
public GrainReference CreateObjectReference(IAddressable obj, IGrainMethodInvoker invoker) { if (obj is GrainReference) { throw new ArgumentException("Argument obj is already a grain reference.", nameof(obj)); } if (obj is Grain) { throw new ArgumentException("Argument must not be a grain class.", nameof(obj)); } var observerId = ObserverGrainId.Create(this.clientId); GrainReference reference = GrainReference.NewObserverGrainReference(observerId, this.GrainReferenceRuntime); if (!localObjects.TryRegister(obj, observerId, invoker)) { throw new ArgumentException($"Failed to add new observer {reference} to localObjects collection.", "reference"); } return(reference); }
public async Task<object> Invoke(MethodInfo methodInfo, InvokeMethodRequest request, IGrainMethodInvoker invoker) { if (methodInfo.Name == "One" && methodInfo.GetParameters().Length == 0) { return "intercepted one with no args"; } var result = await invoker.Invoke(this, request); // To prove that the MethodInfo is from the implementation and not the interface, // we check for this attribute which is only present on the implementation. This could be // done in a simpler fashion, but this demonstrates a potential usage scenario. var shouldMessWithResult = methodInfo.GetCustomAttribute<MessWithResultAttribute>(); var resultString = result as string; if (shouldMessWithResult != null && resultString !=null) { result = string.Concat(resultString.Reverse()); } return result; }
IGrainMethodInvoker IInvokable.GetInvoker(GrainTypeManager typeManager, int interfaceId, string genericGrainType) { // Return previous cached invoker, if applicable if (lastInvoker != null && interfaceId == lastInvoker.InterfaceId) // extension invoker returns InterfaceId==0, so this condition will never be true if an extension is installed { return(lastInvoker); } if (extensionInvoker != null && extensionInvoker.IsExtensionInstalled(interfaceId)) { // Shared invoker for all extensions installed on this target lastInvoker = extensionInvoker; } else { // Find the specific invoker for this interface / grain type lastInvoker = typeManager.GetInvoker(interfaceId, genericGrainType); } return(lastInvoker); }
public IGrainMethodInvoker GetInvoker(string genericGrainType = null) { // if the grain class is non-generic if (!this.isGeneric) { return(invoker ?? (invoker = (IGrainMethodInvoker)Activator.CreateInstance(baseInvokerType))); } if (this.cachedGenericInvokers.TryGetValue(genericGrainType, out IGrainMethodInvoker result)) { return(result); } var typeArgs = TypeUtils.GenericTypeArgsFromArgsString(genericGrainType); var concreteType = this.baseInvokerType.MakeGenericType(typeArgs); var inv = (IGrainMethodInvoker)Activator.CreateInstance(concreteType); this.cachedGenericInvokers.TryAdd(genericGrainType, inv); return(inv); }
public OrleansHttpGatewayMiddleware(RequestDelegate next, IOptions <OrleansHttpGatewayOptions> config, JsonSerializer serializer, IGrainBuilder grainBuilder, IGrainMethodInvoker grainMethodInvoker, IRouteDataResolve routeDataResolve, ILogger <OrleansHttpGatewayMiddleware> logger) { if (config == null) { throw new ArgumentNullException(nameof(config)); } this._routeDataResolve = routeDataResolve; this._options = config.Value; this._grainBuilder = grainBuilder ?? throw new ArgumentNullException(nameof(grainBuilder)); this._grainInvoker = grainMethodInvoker; this._logger = logger; _serializer = serializer; _next = next; }
/// <summary> /// Returns a new <see cref="InterceptedMethodInvoker"/> for the provided values. /// </summary> /// <param name="implementationType">The grain type.</param> /// <param name="interfaceId">The interface id.</param> /// <param name="invoker">The invoker.</param> /// <returns>A new <see cref="InterceptedMethodInvoker"/> for the provided values.</returns> private static InterceptedMethodInvoker CreateInterceptedMethodInvoker( Type implementationType, int interfaceId, IGrainMethodInvoker invoker) { // If a grain extension is being invoked, the implementation map must match the methods on the extension // and not the grain implementation. var extensionMap = invoker as IGrainExtensionMap; if (extensionMap != null) { IGrainExtension extension; if (extensionMap.TryGetExtension(interfaceId, out extension)) { implementationType = extension.GetType(); } } var implementationMap = GetInterfaceToImplementationMap(interfaceId, implementationType); return(new InterceptedMethodInvoker(invoker, implementationMap)); }
public async static System.Threading.Tasks.Task<IClientObserver> CreateObjectReference(IClientObserver obj) { if (methodInvoker == null) methodInvoker = new ClientObserverMethodInvoker(); return ClientObserverFactory.Cast(await GrainReference.CreateObjectReference(obj, methodInvoker)); }
private Task<object> InvokeWithInterceptors(IAddressable target, InvokeMethodRequest request, IGrainMethodInvoker invoker) { // If the target has a grain-level interceptor or there is a silo-level interceptor, intercept the // call. var siloWideInterceptor = SiloProviderRuntime.Instance.GetInvokeInterceptor(); var grainWithInterceptor = target as IGrainInvokeInterceptor; // Silo-wide interceptors do not operate on system targets. var hasSiloWideInterceptor = siloWideInterceptor != null && target is IGrain; var hasGrainLevelInterceptor = grainWithInterceptor != null; if (!hasGrainLevelInterceptor && !hasSiloWideInterceptor) { // The call is not intercepted at either the silo or the grain level, so call the invoker // directly. return invoker.Invoke(target, request); } // Get an invoker which delegates to the grain's IGrainInvocationInterceptor implementation. // If the grain does not implement IGrainInvocationInterceptor, then the invoker simply delegates // calls to the provided invoker. var interceptedMethodInvoker = interceptedMethodInvokerCache.GetOrCreate( target.GetType(), request.InterfaceId, invoker); var methodInfo = interceptedMethodInvoker.GetMethodInfo(request.MethodId); if (hasSiloWideInterceptor) { // There is a silo-level interceptor and possibly a grain-level interceptor. // As a minor optimization, only pass the intercepted invoker if there is a grain-level // interceptor. return siloWideInterceptor( methodInfo, request, (IGrain)target, hasGrainLevelInterceptor ? interceptedMethodInvoker : invoker); } // The grain has an invoke method, but there is no silo-wide interceptor. return grainWithInterceptor.Invoke(methodInfo, request, invoker); }
public async static System.Threading.Tasks.Task<IObserve> CreateObjectReference(IObserve obj) { if (methodInvoker == null) methodInvoker = new ObserveMethodInvoker(); return ObserveFactory.Cast(await GrainReference.CreateObjectReference(obj, methodInvoker)); }
public GrainReference CreateObjectReference(IAddressable obj, IGrainMethodInvoker invoker) { throw new InvalidOperationException("Cannot create a local object reference from a grain."); }
public IGrainMethodInvoker GetInvoker(string genericGrainType = null) { // if the grain class is non-generic if (cachedGenericInvokersLockObj == null) { return invoker ?? (invoker = (IGrainMethodInvoker)Activator.CreateInstance(baseInvokerType)); } else { lock (cachedGenericInvokersLockObj) { if (cachedGenericInvokers.ContainsKey(genericGrainType)) return cachedGenericInvokers[genericGrainType]; } var typeArgs = TypeUtils.GenericTypeArgsFromArgsString(genericGrainType); var concreteType = baseInvokerType.MakeGenericType(typeArgs); var inv = (IGrainMethodInvoker)Activator.CreateInstance(concreteType); lock (cachedGenericInvokersLockObj) { if (!cachedGenericInvokers.ContainsKey(genericGrainType)) cachedGenericInvokers[genericGrainType] = inv; } return inv; } }
public Task <object> Invoke(MethodInfo methodInfo, InvokeMethodRequest request, IGrainMethodInvoker invoker) { if (methodInfo.Name == nameof(GetInputAsString)) { return(Task.FromResult <object>($"Hah! You wanted {request.Arguments[0]}, but you got me!")); } return(invoker.Invoke(this, request)); }
public GrainReference CreateObjectReference(IAddressable obj, IGrainMethodInvoker invoker) { if (obj is GrainReference) throw new ArgumentException("Argument obj is already a grain reference."); GrainReference gr = GrainReference.NewObserverGrainReference(clientId, GuidId.GetNewGuidId()); if (!localObjects.TryAdd(gr.ObserverId, new LocalObjectData(obj, gr.ObserverId, invoker))) { throw new ArgumentException(String.Format("Failed to add new observer {0} to localObjects collection.", gr), "gr"); } return gr; }
// capture stats async Task<object> InvokeInterceptor(MethodInfo targetMethod, InvokeMethodRequest request, IGrain grain, IGrainMethodInvoker invoker) { var grainName = grain.GetType().FullName; var stopwatch = Stopwatch.StartNew(); // invoke grain object result = null; var isException = false; try { if (this.innerInterceptor != null) { result = await this.innerInterceptor(targetMethod, request, grain, invoker); } else { result = await invoker.Invoke(grain, request); } } catch (Exception ex) { isException = true; throw; } finally { try { stopwatch.Stop(); var elapsedMs = (double)stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond; var key = string.Format("{0}.{1}", grainName, targetMethod?.Name ?? "Unknown"); grainTrace.AddOrUpdate(key, _ => { return new GrainTraceEntry { Count = 1, ExceptionCount = (isException ? 1 : 0), SiloAddress = siloAddress, ElapsedTime = elapsedMs, Grain = grainName , Method = targetMethod?.Name ?? "Unknown", Period = DateTime.UtcNow }; }, (_, last) => { last.Count += 1; last.ElapsedTime += elapsedMs; if (isException) last.ExceptionCount += 1; return last; }); } catch (Exception ex) { this.Logger.Error(100002, "error recording results for grain", ex); } } return result; }
public InterceptedMethodInvoker(IGrainMethodInvoker invoker, IReadOnlyDictionary<int, MethodInfo> methodInfos) { this.invoker = invoker; this.methodInfos = methodInfos; }
// capture stats async Task <object> InvokeInterceptor(MethodInfo targetMethod, InvokeMethodRequest request, IGrain grain, IGrainMethodInvoker invoker) { var grainName = grain.GetType().FullName; var stopwatch = Stopwatch.StartNew(); // invoke grain object result = null; var isException = false; try { if (this.innerInterceptor != null) { result = await this.innerInterceptor(targetMethod, request, grain, invoker).ConfigureAwait(false); } else { result = await invoker.Invoke(grain, request).ConfigureAwait(false); } } catch (Exception) { isException = true; throw; } finally { try { stopwatch.Stop(); var elapsedMs = (double)stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond; var key = string.Format("{0}.{1}", grainName, formatMethodName(targetMethod, request, grain)); grainTrace.AddOrUpdate(key, _ => { return(new GrainTraceEntry { Count = 1, ExceptionCount = (isException ? 1 : 0), SiloAddress = siloAddress, ElapsedTime = elapsedMs, Grain = grainName, Method = formatMethodName(targetMethod, request, grain), Period = DateTime.UtcNow }); }, (_, last) => { last.Count += 1; last.ElapsedTime += elapsedMs; if (isException) { last.ExceptionCount += 1; } return(last); }); } catch (Exception ex) { this.Logger.Error(100002, "error recording results for grain", ex); } } return(result); }
private Task <object> InvokeWithInterceptors(IAddressable target, InvokeMethodRequest request, IGrainMethodInvoker invoker) { // If the target has a grain-level interceptor or there is a silo-level interceptor, intercept the // call. var siloWideInterceptor = this.CurrentStreamProviderRuntime.GetInvokeInterceptor(); var grainWithInterceptor = target as IGrainInvokeInterceptor; // Silo-wide interceptors do not operate on system targets. var hasSiloWideInterceptor = siloWideInterceptor != null && target is IGrain; var hasGrainLevelInterceptor = grainWithInterceptor != null; if (!hasGrainLevelInterceptor && !hasSiloWideInterceptor) { // The call is not intercepted at either the silo or the grain level, so call the invoker // directly. return(invoker.Invoke(target, request)); } // If the request is intended for an extension object, use that as the implementation type, otherwise use // the target object. Type implementationType; var extensionMap = invoker as IGrainExtensionMap; IGrainExtension extension; if (extensionMap != null && extensionMap.TryGetExtension(request.InterfaceId, out extension)) { implementationType = extension.GetType(); } else { implementationType = target.GetType(); } // Get an invoker which delegates to the grain's IGrainInvocationInterceptor implementation. // If the grain does not implement IGrainInvocationInterceptor, then the invoker simply delegates // calls to the provided invoker. var interceptedMethodInvoker = interceptedMethodInvokerCache.GetOrCreate( implementationType, request.InterfaceId, invoker); var methodInfo = interceptedMethodInvoker.GetMethodInfo(request.MethodId); if (hasSiloWideInterceptor) { // There is a silo-level interceptor and possibly a grain-level interceptor. // As a minor optimization, only pass the intercepted invoker if there is a grain-level // interceptor. return(siloWideInterceptor( methodInfo, request, (IGrain)target, hasGrainLevelInterceptor ? interceptedMethodInvoker : invoker)); } // The grain has an invoke method, but there is no silo-wide interceptor. return(grainWithInterceptor.Invoke(methodInfo, request, invoker)); }
/// <summary> /// Called from generated code. /// </summary> public static Task <GrainReference> CreateObjectReference(IAddressable o, IGrainMethodInvoker invoker) { return(Task.FromResult(RuntimeClient.Current.CreateObjectReference(o, invoker))); }
public IGrainMethodInvoker GetInvoker(int interfaceId, string genericGrainType=null) { // Return previous cached invoker, if applicable if (lastInvoker != null && interfaceId == lastInvoker.InterfaceId) // extension invoker returns InterfaceId==0, so this condition will never be true if an extension is installed return lastInvoker; if (extensionInvoker != null && extensionInvoker.IsExtensionInstalled(interfaceId)) // HasExtensionInstalled(interfaceId) // Shared invoker for all extensions installed on this grain lastInvoker = extensionInvoker; else // Find the specific invoker for this interface / grain type lastInvoker = RuntimeClient.Current.GetInvoker(interfaceId, genericGrainType); return lastInvoker; }
internal LocalObjectData(IAddressable obj, GuidId observerId, IGrainMethodInvoker invoker) { LocalObject = new WeakReference(obj); ObserverId = observerId; Invoker = invoker; Messages = new Queue<Message>(); Running = false; }
public IGrainMethodInvoker GetInvoker(string genericGrainType = null) { if (String.IsNullOrEmpty(genericGrainType)) return invoker ?? (invoker = (IGrainMethodInvoker) Activator.CreateInstance(baseInvokerType)); lock (cachedGenericInvokersLockObj) { if (cachedGenericInvokers.ContainsKey(genericGrainType)) return cachedGenericInvokers[genericGrainType]; } var typeArgs = TypeUtils.GenericTypeArgs(genericGrainType); var concreteType = baseInvokerType.MakeGenericType(typeArgs); var inv = (IGrainMethodInvoker) Activator.CreateInstance(concreteType); lock (cachedGenericInvokersLockObj) { if (!cachedGenericInvokers.ContainsKey(genericGrainType)) cachedGenericInvokers[genericGrainType] = inv; } return inv; }
private bool TryInstallExtension(int interfaceId, IInvokable invokable, string genericGrainType, ref IGrainMethodInvoker invoker) { IGrainExtension extension = TryGetCurrentActivationData(out ActivationData activationData) ? activationData.ActivationServices.GetServiceByKey <int, IGrainExtension>(interfaceId) : this.ServiceProvider.GetServiceByKey <int, IGrainExtension>(interfaceId); if (extension == null) { return(false); } if (!TryAddExtension(extension)) { return(false); } // Get the newly installed invoker for the grain extension. invoker = invokable.GetInvoker(typeManager, interfaceId, genericGrainType); return(true); }
/// <summary> /// Creates and returns a map from interface id to intercepted invoker for constructed generic types. /// </summary> /// <param name="implementationType">The implementation type.</param> /// <param name="invoker">The underlying invoker.</param> /// <returns>A map from interface id to intercepted invoker.</returns> private static Dictionary<int, InterceptedMethodInvoker> CreateMapForConstructedGeneric( Type implementationType, IGrainMethodInvoker invoker) { // It is important to note that the interfaceId and methodId are computed based upon the non-concrete // version of the implementation type. During code generation, the concrete type would not be available // and therefore the generic type definition is used. if (!implementationType.IsConstructedGenericType) { throw new InvalidOperationException( $"Type {implementationType} passed to {nameof(CreateMapForConstructedGeneric)} is not a constructed generic type"); } var genericClass = implementationType.GetGenericTypeDefinition(); var genericClassTypeInfo = genericClass.GetTypeInfo(); var implementationTypeInfo = implementationType.GetTypeInfo(); var genericInterfaces = genericClass.GetInterfaces(); var concreteInterfaces = implementationType.GetInterfaces(); // Create an invoker for every interface on the provided type. var result = new Dictionary<int, InterceptedMethodInvoker>(genericInterfaces.Length); for (var i = 0; i < genericInterfaces.Length; i++) { // Because these methods are identical except for type parameters, their methods should also be identical except // for type parameters, including identical ordering. That is the assumption. var genericMethods = GrainInterfaceUtils.GetMethods(genericInterfaces[i]); var concreteInterfaceMethods = GrainInterfaceUtils.GetMethods(concreteInterfaces[i]); // Map every method on this interface from the definition interface onto the implementation class. var methodMap = new Dictionary<int, MethodInfo>(genericMethods.Length); var genericMap = default(InterfaceMapping); var concreteMap = default(InterfaceMapping); for (var j = 0; j < genericMethods.Length; j++) { // If this method is not from the expected interface (eg, because it's from a parent interface), then // get the mapping for the interface which it does belong to. var genericInterfaceMethod = genericMethods[j]; if (genericMap.InterfaceType != genericInterfaceMethod.DeclaringType) { genericMap = genericClassTypeInfo.GetRuntimeInterfaceMap(genericInterfaceMethod.DeclaringType); concreteMap = implementationTypeInfo.GetRuntimeInterfaceMap(concreteInterfaceMethods[j].DeclaringType); } // Determine the position in the definition's map which the target method belongs to and take the implementation // from the same position on the implementation's map. for (var k = 0; k < genericMap.InterfaceMethods.Length; k++) { if (genericMap.InterfaceMethods[k] != genericInterfaceMethod) continue; methodMap[GrainInterfaceUtils.ComputeMethodId(genericInterfaceMethod)] = concreteMap.TargetMethods[k]; break; } } // Add the resulting map of methodId -> method to the interface map. var interfaceId = GrainInterfaceUtils.GetGrainInterfaceId(genericInterfaces[i]); result[interfaceId] = new InterceptedMethodInvoker(invoker, methodMap); } return result; }
private async Task <object> Interceptor(MethodInfo targetMethod, InvokeMethodRequest request, IGrain target, IGrainMethodInvoker invoker) { if (targetMethod == null) { throw new ArgumentNullException(nameof(targetMethod)); } var declaringNameSpace = targetMethod.DeclaringType?.Namespace; // Do not intercept Orleans grains or other grains which should not be included in statistics. if (targetMethod.DeclaringType.GetCustomAttribute <ExcludeGrainFromStatisticsAttribute>() != null || declaringNameSpace?.StartsWith("Orleans") == true) { return(await invoker.Invoke(target, request)); } RequestTimings.GetOrCreate(); // Ensure request timings is created here and not in the grain call. RequestTimings.Current.Request.Start(); Exception ex = null; try { return(await invoker.Invoke(target, request)); } catch (Exception e) { ex = e; throw; } finally { RequestTimings.Current.Request.Stop(); var grainEvent = EventPublisher.CreateEvent(); if (target.GetPrimaryKeyString() != null) { grainEvent.GrainKeyString = target.GetPrimaryKeyString(); } else if (target.IsPrimaryKeyBasedOnLong()) { grainEvent.GrainKeyLong = target.GetPrimaryKeyLong(out var keyExt); grainEvent.GrainKeyExtention = keyExt; } else { grainEvent.GrainKeyGuid = target.GetPrimaryKey(out var keyExt); grainEvent.GrainKeyExtention = keyExt; } if (target is Grain grainTarget) { grainEvent.SiloAddress = grainTarget.RuntimeIdentity; } grainEvent.SiloDeploymentId = ConfigBuilder.ClusterConfiguration.Globals.DeploymentId; grainEvent.TargetType = targetMethod.DeclaringType?.FullName; grainEvent.TargetMethod = targetMethod.Name; grainEvent.Exception = ex; grainEvent.ErrCode = ex != null ? null : (int?)0; try { EventPublisher.TryPublish(grainEvent); } catch (Exception) { EventsDiscarded.Increment(); } } }
/// <summary> /// Constructs a new instance of the <see cref="InterceptedMethodInvoker"/> class. /// </summary> /// <param name="invoker">The underlying method invoker.</param> /// <param name="methodInfos"> /// The mapping between method id and <see cref="MethodInfo"/> for each of the grain's methods. /// </param> public InterceptedMethodInvoker(IGrainMethodInvoker invoker, Dictionary <int, MethodInfo> methodInfos) { this.invoker = invoker; this.methodInfos = methodInfos; }