/// <summary> /// Constructor /// </summary> /// <param name="actorKey">actor key</param> /// <param name="actorManager">actor manager</param> public ActorBase(ActorKey actorKey, IActorManager actorManager) { Verify.IsNotNull(nameof(actorKey), actorKey); Verify.IsNotNull(nameof(actorManager), actorManager); ActorKey = actorKey; ActorManager = actorManager; ActorEventSource.Log.ActorActivate(_workContext.WithTag(_tag), ActorKey, this.GetType()); }
/// <summary> /// Constructor /// </summary> /// <param name="actorKey">actor key</param> /// <param name="actorManager">actor manager</param> public ActorBase(ActorKey actorKey, IActorManager actorManager) { Verify.IsNotNull(nameof(actorKey), actorKey); Verify.IsNotNull(nameof(actorManager), actorManager); ActorKey = actorKey; ActorManager = actorManager; ActorManager.Configuration.ActorCreated(_workContext.WithTag(_tag), ActorKey, this.GetType()); }
/// <summary> /// Constructor /// </summary> /// <param name="actorType">actor type</param> /// <param name="actorKey">actor key</param> /// <param name="instance">instance of the actor class</param> /// <param name="actorProxy">actor proxy</param> public ActorRegistration(Type actorType, ActorKey actorKey, IActorBase instance, IActor actorProxy) { actorType.Verify(nameof(actorType)).IsNotNull(); actorKey.Verify(nameof(actorKey)).IsNotNull(); instance.Verify(nameof(instance)).IsNotNull(); actorProxy.Verify(nameof(actorProxy)).IsNotNull(); ActorType = actorType; ActorKey = actorKey; _instance = instance; _actorProxy = actorProxy; }
/// <summary> /// Constructor /// </summary> /// <param name="actorType">actor type</param> /// <param name="actorKey">actor key</param> /// <param name="instance">instance of the actor class</param> /// <param name="actorProxy">actor proxy</param> public ActorRegistration(Type actorType, ActorKey actorKey, IActorBase instance, IActor actorProxy) { Verify.IsNotNull(nameof(actorType), actorType); Verify.IsNotNull(nameof(actorKey), actorKey); Verify.IsNotNull(nameof(instance), instance); Verify.IsNotNull(nameof(actorProxy), actorProxy); ActorType = actorType; ActorKey = actorKey; _instance = instance; ActorProxy = actorProxy; }
/// <summary> /// Deactivate actor /// </summary> /// <typeparam name="T">actor interface</typeparam> /// <param name="context">context</param> /// <param name="actorKey">actor key</param> /// <returns>true if deactivated, false if not found</returns> public async Task <bool> Deactivate(Type actorType, ActorKey actorKey) { Verify.Assert(IsRunning, _disposedTestText); actorType.Verify(nameof(actorType)).IsNotNull(); IActorRegistration?subject = await _actorRepository.Remove(Configuration.WorkContext.With(_tag), actorType, actorKey).ConfigureAwait(false); if (subject == null) { return(false); } return(true); }
/// <summary> /// Deactivate actor /// </summary> /// <typeparam name="T">actor interface</typeparam> /// <param name="context">context</param> /// <param name="actorKey">actor key</param> /// <returns>true if deactivated, false if not found</returns> public async Task <bool> DeactivateAsync <T>(IWorkContext context, ActorKey actorKey) { Verify.Assert(IsRunning, _disposedTestText); Verify.IsNotNull(nameof(context), context); Verify.IsNotNull(nameof(actorKey), actorKey); IActorRegistration actorRegistration = await _actorRepository.RemoveAsync(context, typeof(T), actorKey); if (actorRegistration == null) { return(false); } return(true); }
/// <summary> /// Lookup actor /// </summary> /// <param name="actorType">actor type</param> /// <param name="actorKey">actor key</param> /// <returns>actor registration or null if not exist</returns> public IActorRegistration Lookup(Type actorType, ActorKey actorKey) { Verify.IsNotNull(nameof(actorType), actorType); Verify.IsNotNull(nameof(actorKey), actorKey); lock (_lock) { var key = new RegistrationKey(actorType, actorKey.Key); if (_actors.TryGetValue(key, out IActorRegistration registration)) { return(registration); } return(null); } }
/// <summary> /// Lookup actor /// </summary> /// <param name="actorType">actor type</param> /// <param name="actorKey">actor key</param> /// <returns>actor registration or null if not exist</returns> public IActorRegistration?Lookup(Type actorType, ActorKey actorKey) { actorType.Verify(nameof(actorType)).IsNotNull(); actorKey.Verify(nameof(actorKey)).IsNotNull(); lock (_lock) { var key = new RegistrationKey(actorType, actorKey.Key); if (_actorCache.TryGetValue(key, out IActorRegistration registration)) { return(registration); } return(null); } }
/// <summary> /// Create actor from either lambda or activator /// </summary> /// <typeparam name="T">actor interface</typeparam> /// <param name="context">context</param> /// <param name="actorKey">actor key</param> /// <param name="manager">actor manager</param> /// <returns>instance of actor implementation</returns> public T Create <T>(IWorkContext context, ActorKey actorKey, IActorManager manager) where T : IActor { Verify.IsNotNull(nameof(context), context); Verify.IsNotNull(nameof(actorKey), actorKey); Verify.IsNotNull(nameof(manager), manager); Verify.Assert(typeof(T).IsInterface, $"{typeof(T)} must be an interface"); context = context.WithTag(_tag); Type actorType = typeof(T); if (!_actorRegistration.TryGetValue(actorType, out ActorTypeRegistration typeRegistration)) { var ex = new KeyNotFoundException($"Registration for {actorType.FullName} was not found"); context.EventLog.Error(context.WithTag(_tag), "create failure", ex); throw ex; } IActor actorObject = typeRegistration.CreateImplementation(context, actorKey, manager); return((T)actorObject); }
/// <summary> /// Create virtual actor, return current instance or create one /// </summary> /// <typeparam name="T">actor interface</typeparam> /// <param name="context">context</param> /// <param name="actorKey">actor key</param> /// <returns>actor proxy interface</returns> public async Task <T> CreateProxyAsync <T>(IWorkContext context, ActorKey actorKey) where T : IActor { Verify.Assert(IsRunning, _disposedTestText); Verify.IsNotNull(nameof(context), context); Verify.IsNotNull(nameof(context), context); Verify.IsNotNull(nameof(actorKey), actorKey); context = context.WithTag(_tag); Type actorType = typeof(T); // Lookup instance of actor (type + actorKey) IActorRegistration actorRegistration = _actorRepository.Lookup(actorType, actorKey); if (actorRegistration != null) { return(actorRegistration.GetInstance <T>()); } // Create actor IActor actorObject = _typeManager.Create <T>(context, actorKey, this); IActorBase actorBase = actorObject as IActorBase; if (actorBase == null) { var ex = new ArgumentException($"Actor {actorObject.GetType().FullName} does not implement IActorBase"); Configuration.WorkContext.EventLog.Error(context, "Cannot create", ex); throw ex; } T actorInterface = ActorProxy <T> .Create(context, actorBase, this); actorRegistration = new ActorRegistration(typeof(T), actorKey, actorBase, actorInterface); await _actorRepository.SetAsync(context, actorRegistration); // Create proxy for interface return(actorRegistration.GetInstance <T>()); }
/// <summary> /// Create actor from either lambda or activator /// </summary> /// <typeparam name="T">actor interface</typeparam> /// <param name="context">context</param> /// <param name="actorKey">actor key</param> /// <param name="manager">actor manager</param> /// <returns>instance of actor implementation</returns> public T Create <T>(IWorkContext context, ActorKey actorKey, IActorManager manager) where T : IActor { context.Verify(nameof(context)).IsNotNull(); actorKey.Verify(nameof(actorKey)).IsNotNull(); manager.Verify(nameof(manager)).IsNotNull(); typeof(T).IsInterface.Verify().Assert(x => x == true, $"{typeof(T)} must be an interface"); context = context.With(_tag); Type actorType = typeof(T); ActorTypeRegistration?typeRegistration = GetTypeRegistration(actorType) ?? GetTypeFromDi(context, actorType); if (typeRegistration == null) { var ex = new KeyNotFoundException($"Registration for {actorType.FullName} was not found"); context.Telemetry.Error(context.With(_tag), "create failure", ex); throw ex; } IActor actorObject = typeRegistration.CreateImplementation(context); // Set actor key and manager ActorBase?actorBase = actorObject as ActorBase; if (actorBase == null) { string failureMsg = $"Created actor type {actorObject.GetType()} does not derive from ActorBase"; context.Telemetry.Error(context.With(_tag), failureMsg); throw new InvalidOperationException(failureMsg); } actorBase.ActorKey = actorKey; actorBase.ActorManager = manager; actorBase.ActorType = actorType; return((T)actorObject); }
/// <summary> /// Create proxy to actor, return current instance or create one /// </summary> /// <typeparam name="T">actor interface</typeparam> /// <param name="context">context</param> /// <param name="actorKey">actor key</param> /// <returns>actor proxy interface</returns> public async Task <T> CreateProxy <T>(ActorKey actorKey) where T : IActor { Verify.Assert(IsRunning, _disposedTestText); actorKey.Verify(nameof(actorKey)).IsNotNull(); Type actorType = typeof(T); // Lookup instance of actor (type + actorKey) IActorRegistration?actorRegistration = _actorRepository.Lookup(actorType, actorKey); if (actorRegistration != null) { return(actorRegistration.GetInstance <T>()); } // Create actor IActor actorObject = _typeManager.Create <T>(Configuration.WorkContext.With(_tag), actorKey, this); IActorBase?actorBase = actorObject as IActorBase; if (actorBase == null) { var ex = new ArgumentException($"Actor {actorObject.GetType().FullName} does not implement IActorBase"); Configuration.WorkContext.Telemetry.Error(Configuration.WorkContext.With(_tag), "Cannot create", ex); throw ex; } // Create proxy T actorInterface = ActorProxy <T> .Create(Configuration.WorkContext.With(_tag), actorBase, this); actorRegistration = new ActorRegistration(typeof(T), actorKey, actorBase, actorInterface); await _actorRepository.Set(Configuration.WorkContext.With(_tag), actorRegistration).ConfigureAwait(false); // Create proxy for interface return(actorRegistration.GetInstance <T>()); }
public static void ActorActivate(this IActorConfiguration configuration, IWorkContext context, ActorKey actorKey, Type actorType, string message = null) { Verify.IsNotNull(nameof(configuration), configuration); Verify.IsNotNull(nameof(actorKey), actorKey); Verify.IsNotNull(nameof(actorType), actorType); IEventDimensions dimensions = new EventDimensionsBuilder() .Add(nameof(actorKey), actorKey) .Add(nameof(actorType), actorType) .Add(nameof(message), message) .Build(); configuration.WorkContext.EventLog.LogEvent(context, TelemetryLevel.Verbose, _actorEventName, nameof(ActorActivate), dimensions); configuration.WorkContext.EventLog.TrackMetric(context, nameof(ActorActivate), dimensions); }
/// <summary> /// Remove actor from container /// </summary> /// <param name="actorType">actor type</param> /// <param name="actorKey">actor key</param> /// <returns>actor registration or null if not exist</returns> public async Task <IActorRegistration?> Remove(IWorkContext context, Type actorType, ActorKey actorKey) { actorType.Verify(nameof(actorType)).IsNotNull(); actorKey.Verify(nameof(actorKey)).IsNotNull(); context = context.With(_tag); context.Telemetry.Verbose(context.With(_tag), $"Removing actor {actorKey}"); IActorRegistration registration; lock (_lock) { var key = new RegistrationKey(actorType, actorKey.Key); if (!_actorCache.TryRemove(key, out registration)) { return(null); } } try { await registration.Instance.Deactivate(context).ConfigureAwait(false); } finally { registration.Instance.Dispose(); } return(registration); }
/// <summary> /// Remove actor from container /// </summary> /// <param name="actorType">actor type</param> /// <param name="actorKey">actor key</param> /// <returns>actor registration or null if not exist</returns> public async Task <IActorRegistration> RemoveAsync(IWorkContext context, Type actorType, ActorKey actorKey) { Verify.IsNotNull(nameof(actorType), actorType); Verify.IsNotNull(nameof(actorKey), actorKey); context = context.WithTag(_tag); context.EventLog.Verbose(context.WithTag(_tag), $"Removing actor {actorKey}"); IActorRegistration registration; lock (_lock) { var key = new RegistrationKey(actorType, actorKey.Key); if (!_actors.TryRemove(key, out registration)) { return(null); } } await registration.Instance.DeactivateAsync(context); registration.Instance.Dispose(); return(registration); }
public static void ActorStopTimerEvent(this ActorConfiguration configuration, IWorkContext context, ActorKey actorKey, string?message = null) { configuration.Verify(nameof(configuration)).IsNotNull(); actorKey.Verify(nameof(actorKey)).IsNotNull(); IEventDimensions dimensions = new EventDimensionsBuilder() .Add(nameof(actorKey), actorKey) .Add(nameof(message), message) .Build(); configuration.WorkContext.Telemetry.LogEvent(context, nameof(ActorStopTimerEvent), dimensions); }
public static void ActorCalled(this IActorConfiguration configuration, IWorkContext context, ActorKey actorKey, Type interfaceType, string methodName, string message = null) { Verify.IsNotNull(nameof(configuration), configuration); Verify.IsNotNull(nameof(actorKey), actorKey); Verify.IsNotNull(nameof(interfaceType), interfaceType); Verify.IsNotEmpty(nameof(methodName), methodName); IEventDimensions dimensions = new EventDimensionsBuilder() .Add(nameof(actorKey), actorKey) .Add(nameof(interfaceType), interfaceType) .Add(nameof(methodName), methodName) .Add(nameof(message), message) .Build(); configuration.WorkContext.EventLog.LogEvent(context, TelemetryLevel.Verbose, _actorEventName, nameof(ActorCalled), dimensions); }