// Called by the Durable client binding infrastructure public DurabilityProvider GetDurabilityProvider(DurableClientAttribute attribute) { // TODO: Much of this logic should go into the base class if (string.IsNullOrEmpty(attribute.ConnectionName) && string.IsNullOrEmpty(attribute.TaskHub)) { return(this.GetDurabilityProvider()); } lock (this.clientProviders) { string key = GetDurabilityProviderKey(attribute); if (this.clientProviders.TryGetValue(key, out DurabilityProvider clientProvider)) { return(clientProvider); } SqlDurabilityOptions clientOptions = this.GetSqlOptions(attribute); IOrchestrationServiceClient serviceClient = new SqlOrchestrationService(clientOptions.GetOrchestrationServiceSettings( this.extensionOptions, this.connectionStringResolver)); clientProvider = new SqlDurabilityProvider( this.GetOrchestrationService(), clientOptions, serviceClient); this.clientProviders.Add(key, clientProvider); return(clientProvider); } }
public async Task ScaleRecommendation_PendingActivities(int activityCount, int expectedRecommendation) { // Block the activity dispatch loop so that we can queue activities without running them this.testService.OrchestrationServiceMock.Setup( svc => svc.LockNextTaskActivityWorkItem( It.IsAny <TimeSpan>(), It.IsAny <CancellationToken>())) .Returns(() => Task.Delay(100).ContinueWith(t => default(TaskActivityWorkItem))); // We can influence the recommended replica count by modifying concurrency settings this.testService.OrchestrationServiceOptions.MaxConcurrentActivities = 3; await this.testService.StartWorkerAsync(); SqlOrchestrationService orchestrationService = this.testService.OrchestrationServiceMock.Object; // Initial scale recommendation should be zero int recommendation = await orchestrationService.GetRecommendedReplicaCountAsync(); Assert.Equal(0, recommendation); TestInstance <string> instance = await this.testService.RunOrchestration <string[], string>( null, orchestrationName : "OrchestrationWithActivityFanOut", implementation : (ctx, _) => { return(Task.WhenAll(Enumerable.Range(0, activityCount).Select(i => ctx.ScheduleTask <string>("ToString", "", i)).ToArray())); }, activities : new[] {
public SqlDurabilityProvider( SqlOrchestrationService service, SqlDurabilityOptions durabilityOptions) : base(Name, service, service, durabilityOptions.ConnectionStringName) { this.service = service ?? throw new ArgumentNullException(nameof(service)); this.durabilityOptions = durabilityOptions; }
// Called by the Durable trigger binding infrastructure public DurabilityProvider GetDurabilityProvider() { if (this.defaultProvider == null) { SqlDurabilityOptions sqlProviderOptions = this.GetDefaultSqlOptions(); SqlOrchestrationService service = this.GetOrchestrationService(); this.defaultProvider = new SqlDurabilityProvider(service, sqlProviderOptions); } return(this.defaultProvider); }
public async Task ScaleRecommendation_PendingOrchestrationStarts() { // Block the orchestration dispatch loop so that we can queue orchestrations without running them this.testService.OrchestrationServiceMock.Setup( svc => svc.LockNextTaskOrchestrationWorkItemAsync( It.IsAny <TimeSpan>(), It.IsAny <CancellationToken>())) .Returns(() => Task.Delay(100).ContinueWith(t => default(TaskOrchestrationWorkItem))); // We can influence the recommended replica count by modifying concurrency settings this.testService.OrchestrationServiceOptions.MaxActiveOrchestrations = 1; await this.testService.StartWorkerAsync(); SqlOrchestrationService orchestrationService = this.testService.OrchestrationServiceMock.Object; // Initial scale recommendation should be zero int recommendation = await orchestrationService.GetRecommendedReplicaCountAsync(); Assert.Equal(0, recommendation); for (int i = 1; i <= 10; i++) { // Schedule an orchestration (it won't run, see above) await this.testService.RunOrchestration( null as string, $"EmptyOrchestration{i:00}", implementation : (ctx, input) => Task.FromResult(input)); // Scale recommendation increments with every new scheduled orchestration. // We pass in the previous recommendation to generate a log statement about the change. recommendation = await orchestrationService.GetRecommendedReplicaCountAsync(recommendation); Assert.Equal(i, recommendation); } // Validate the logs IReadOnlyList <LogEntry> recommendationChangeLogs = this.GetRecommendationChangeLogs(); Assert.Equal(10, recommendationChangeLogs.Count); for (int i = 0; i < recommendationChangeLogs.Count; i++) { LogEntry log = recommendationChangeLogs[i]; LogAssert.FieldEquals(log, "CurrentCount", i); LogAssert.FieldEquals(log, "RecommendedCount", i + 1); } }
public SqlScaleMonitor(SqlOrchestrationService service, string taskHubName) { this.service = service ?? throw new ArgumentNullException(nameof(service)); this.Descriptor = new ScaleMonitorDescriptor($"DurableTask-SqlServer:{taskHubName ?? "default"}"); }
public static async Task InitializeDatabaseAsync() { var options = new SqlOrchestrationServiceSettings(GetDefaultConnectionString()); var service = new SqlOrchestrationService(options); await service.CreateIfNotExistsAsync(); }