internal ServiceCommand(IJellyfishContext context, IClock clock, string commandGroup = null, string commandName = null, string threadPoolKey = null, CommandPropertiesBuilder properties = null, ICircuitBreaker circuitBreaker = null, CommandMetrics metrics = null, CommandExecutionHook executionHook = null) { Contract.Requires(context != null); CommandState state = _states.GetOrAdd(this.GetType().FullName, (n) => ServiceCommandHelper.PrepareInternal(this.GetType(), context, commandGroup, commandName, properties, clock, metrics, circuitBreaker)); if (String.IsNullOrEmpty(state.CommandGroup)) { throw new ArgumentException("commandGroup can not be null or empty."); } Logger = context.GetService <ILoggerFactory>()?.CreateLogger(this.GetType().FullName) ?? EmptyLogger.Instance; CommandGroup = state.CommandGroup; CommandName = state.CommandName; _clock = clock ?? Clock.GetInstance(); // for test Properties = properties?.Build(CommandName) ?? new CommandProperties(CommandName); Metrics = metrics ?? CommandMetricsFactory.GetInstance(CommandName, CommandGroup, Properties, _clock); _circuitBreaker = circuitBreaker ?? (Properties.CircuitBreakerEnabled.Value ? CircuitBreakerFactory.GetOrCreateInstance(CommandName, Properties, Metrics, _clock) : new NoOpCircuitBreaker()); context.MetricsPublisher.CreateOrRetrievePublisherForCommand(CommandGroup, Metrics, _circuitBreaker); this._flags = state.Flags; _threadPoolKey = threadPoolKey ?? CommandGroup; _executionResult = new ExecutionResult(); _executionHook = executionHook ?? context.CommandExecutionHook; var executionPolicy = Properties.ExecutionIsolationStrategy.Value; if (executionPolicy == ExecutionIsolationStrategy.Semaphore) { _flags |= ServiceCommandOptions.SemaphoreExecutionStrategy; } if (executionPolicy == ExecutionIsolationStrategy.Thread) { _flags |= ServiceCommandOptions.ThreadExecutionStrategy; } if (Properties.RequestLogEnabled.Value) { _currentRequestLog = context.GetRequestLog(); } if ((_flags & ServiceCommandOptions.HasCacheKey) == ServiceCommandOptions.HasCacheKey && Properties.RequestCacheEnabled.Value) { _requestCache = context.GetCache <CacheItem>(CommandName); } }
internal static CommandState PrepareInternal(Type commandType, IJellyfishContext context, string commandGroup, string commandName, CommandPropertiesBuilder propertiesBuilder=null, IClock clock = null, CommandMetrics metrics = null, ICircuitBreaker circuitBreaker = null) { var state = new CommandState(); state.CommandName = commandName ?? commandType.FullName; state.CommandGroup = commandGroup ?? state.CommandName; clock = clock ?? Clock.GetInstance(); var properties = propertiesBuilder?.Build( state.CommandName ) ?? new CommandProperties( state.CommandName ); metrics = metrics ?? CommandMetricsFactory.GetInstance( state.CommandName, state.CommandGroup, properties, clock ); circuitBreaker = circuitBreaker ?? ( properties.CircuitBreakerEnabled.Value ? CircuitBreakerFactory.GetOrCreateInstance( state.CommandName, properties, metrics, clock ) : new NoOpCircuitBreaker() ); context.MetricsPublisher.CreateOrRetrievePublisherForCommand( state.CommandGroup, metrics, circuitBreaker ); ServiceCommandOptions flags = ServiceCommandOptions.None; if(IsMethodImplemented( commandType, "GetFallback" )) flags |= ServiceCommandOptions.HasFallBack; if(IsMethodImplemented( commandType, "GetCacheKey" )) flags |= ServiceCommandOptions.HasCacheKey; state.Flags = flags; return state; }