Skip to content

Commit

Permalink
Merge pull request microsoft#78 from microsoft/users/tracyboehrer/que…
Browse files Browse the repository at this point in the history
…ue-options

Added AdapterOptions to control CloudAdapter
  • Loading branch information
tracyboehrer authored Feb 1, 2025
2 parents cbf9908 + ea26d42 commit 8e22337
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 41 deletions.
4 changes: 2 additions & 2 deletions src/Microsoft.Agents.SDK.sln
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ Global
{BC5EFA6C-7EB5-4803-B7C5-093892E9DBB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC5EFA6C-7EB5-4803-B7C5-093892E9DBB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC5EFA6C-7EB5-4803-B7C5-093892E9DBB8}.Release|Any CPU.Build.0 = Release|Any CPU
{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}.Release|Any CPU.Build.0 = Release|Any CPU
Expand Down Expand Up @@ -399,7 +399,7 @@ Global
{7D1A1CE5-6D9B-4D31-AC77-C3B1787F575D} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
{06E490F7-F0BB-E3C4-54FE-5210627292A1} = {183D0E91-B84E-46D7-B653-6D85B4CCF804}
{BC5EFA6C-7EB5-4803-B7C5-093892E9DBB8} = {183D0E91-B84E-46D7-B653-6D85B4CCF804}
{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F1E8E538-309A-46F8-9CE7-AEC6589FAE60}
Expand Down
11 changes: 11 additions & 0 deletions src/libraries/Hosting/AspNetCore/AdapterOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Agents.Hosting.AspNetCore
{
public class AdapterOptions
{
public bool Async { get; set; } = true;
public int ShutdownTimeoutSeconds { get; set; } = 60;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
Expand All @@ -31,15 +30,14 @@ public class HostedTaskService : BackgroundService
/// <remarks>
/// It is important to note that exceptions on the background thread are only logged in the <see cref="ILogger"/>.
/// </remarks>
/// <param name="config"><see cref="IConfiguration"/> used to retrieve ShutdownTimeoutSeconds from appsettings.</param>
/// <param name="taskQueue"><see cref="ActivityTaskQueue"/> implementation where tasks are queued to be processed.</param>
/// <param name="logger"><see cref="ILogger"/> implementation, for logging including background thread exception information.</param>
public HostedTaskService(IConfiguration config, IBackgroundTaskQueue taskQueue, ILogger<HostedTaskService> logger)
/// <param name="options"></param>
public HostedTaskService(IBackgroundTaskQueue taskQueue, ILogger<HostedTaskService> logger, AdapterOptions options = null)
{
ArgumentNullException.ThrowIfNull(config);
ArgumentNullException.ThrowIfNull(taskQueue);

_shutdownTimeoutSeconds = config.GetValue<int>("ShutdownTimeoutSeconds");
_shutdownTimeoutSeconds = options != null ? options.ShutdownTimeoutSeconds : 60;
_taskQueue = taskQueue;
_logger = logger ?? NullLogger<HostedTaskService>.Instance;;
}
Expand Down
28 changes: 14 additions & 14 deletions src/libraries/Hosting/AspNetCore/CloudAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,32 @@ namespace Microsoft.Agents.Hosting.AspNetCore
/// processed by the configured background service if possible.
/// </summary>
/// <remarks>
/// If the activity is not an Invoke, and DeliveryMode is not ExpectReplies, and this
/// is not a GET request to upgrade to WebSockets, then the activity will be enqueued for processing
/// on a background thread.
/// Invoke and ExpectReplies are always handled synchronously.
/// </remarks>
/// <remarks>
/// Create an instance of <see cref="CloudAdapter"/>.
/// </remarks>
/// <param name="configuration"></param>
/// <param name="logger"></param>
/// <param name="activityTaskQueue"></param>
/// <param name="channelServiceClientFactory"></param>
public class CloudAdapter
: ChannelServiceAdapterBase, IBotHttpAdapter
{
private readonly IActivityTaskQueue _activityTaskQueue;
private readonly bool _async;
private readonly AdapterOptions _adapterOptions;

/// <summary>
///
/// </summary>
/// <param name="channelServiceClientFactory"></param>
/// <param name="activityTaskQueue"></param>
/// <param name="logger"></param>
/// <param name="options">Defaults to Async enabled and 60 second shutdown delay timeout</param>
/// <param name="middlewares"></param>
/// <exception cref="ArgumentNullException"></exception>
public CloudAdapter(
IChannelServiceClientFactory channelServiceClientFactory,
IActivityTaskQueue activityTaskQueue,
ILogger<IBotHttpAdapter> logger = null,
bool async = true,
AdapterOptions options = null,
Core.Interfaces.IMiddleware[] middlewares = null) : base(channelServiceClientFactory, logger)
{
_activityTaskQueue = activityTaskQueue ?? throw new ArgumentNullException(nameof(activityTaskQueue));
_async = async;
_adapterOptions = options ?? new AdapterOptions() { Async = true, ShutdownTimeoutSeconds = 60 };

if (middlewares != null)
{
Expand Down Expand Up @@ -116,7 +116,7 @@ public async Task ProcessAsync(HttpRequest httpRequest, HttpResponse httpRespons

try
{
if (!_async || activity.Type == ActivityTypes.Invoke || activity.DeliveryMode == DeliveryModes.ExpectReplies)
if (!_adapterOptions.Async || activity.Type == ActivityTypes.Invoke || activity.DeliveryMode == DeliveryModes.ExpectReplies)
{
// Invoke and ExpectReplies cannot be performed async, the response must be written before the calling thread is released.
// Process the inbound activity with the bot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ protected override async Task<MessagingExtensionResponse> OnTeamsMessagingExtens

var packages = await FindPackages(text);

// Provide a default icon URL
var defaultIconUrl = "https://api.nuget.org/v3-flatcontainer/newtonsoft.json/13.0.3/icon";

// We take every row of the results and wrap them in cards wrapped in MessagingExtensionAttachment objects.
// The Preview is optional, if it includes a Tap, that will trigger the OnTeamsMessagingExtensionSelectItemAsync event back on this bot.
var attachments = packages.Select(package =>
Expand Down
2 changes: 1 addition & 1 deletion src/samples/Teams/bot-tag-mention/Dialogs/MainDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ await stepContext.Context.SendActivityAsync(
client = new SimpleGraphClient(tokenResponse.Token);
teamDetails = await TeamsInfo.GetTeamDetailsAsync(stepContext.Context, stepContext.Context.Activity.TeamsGetTeamInfo().Id, cancellationToken);
}
catch (Exception ex)
catch (Exception)
{
await stepContext.Context.SendActivityAsync(
"You don't have Graph API permissions to fetch tag's information. Please use this command to mention a tag: \"`@<Bot-name> @<your-tag>`\" to experience tag mention using bot.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Microsoft.Agents.BotBuilder.TestBot.Shared.Debugging
{
public class DebugAdapter : CloudAdapter
{
public DebugAdapter(IChannelServiceClientFactory channelServiceClientFactory, IActivityTaskQueue activityTaskQueue) : base(channelServiceClientFactory, activityTaskQueue, async: false)
public DebugAdapter(IChannelServiceClientFactory channelServiceClientFactory, IActivityTaskQueue activityTaskQueue) : base(channelServiceClientFactory, activityTaskQueue, options: new AdapterOptions() { Async = false })
{
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,13 @@ namespace Microsoft.Agents.Hosting.AspNetCore.Tests.BackgroundTaskService
{
public class HostedTaskServiceTests
{
[Fact]
public void Constructor_ShouldThrowWithNullConfig()
{
var queue = new BackgroundTaskQueue();
var logger = new Mock<ILogger<HostedTaskService>>();

Assert.Throws<ArgumentNullException>(() => new HostedTaskService(null, queue, logger.Object));
}

[Fact]
public void Constructor_ShouldThrowWithNullTaskQueue()
{
var config = new ConfigurationBuilder().Build();
var logger = new Mock<ILogger<HostedTaskService>>();

Assert.Throws<ArgumentNullException>(() => new HostedTaskService(config, null, logger.Object));
Assert.Throws<ArgumentNullException>(() => new HostedTaskService(null, logger.Object));
}

[Fact]
Expand All @@ -40,7 +31,7 @@ public async Task Constructor_ShouldInstantiateNullLogger()

try
{
var service = new HostedTaskService(config, queue, null);
var service = new HostedTaskService(queue, null);
await service.StopAsync(CancellationToken.None);
}
catch (Exception)
Expand Down Expand Up @@ -125,7 +116,7 @@ private static Record UseRecord()
var queue = new BackgroundTaskQueue();
var logger = new Mock<ILogger<HostedTaskService>>();

var service = new HostedTaskService(config, queue, logger.Object);
var service = new HostedTaskService(queue, logger.Object);
return new(service, queue, logger);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ private static Record UseRecord()
var logger = new Mock<ILogger<IBotHttpAdapter>>();
var middleware = new Mock<Core.Interfaces.IMiddleware>();

var adapter = new TestAdapter(factory.Object, queue.Object, logger.Object, true, middleware.Object);
var adapter = new TestAdapter(factory.Object, queue.Object, logger.Object, middlewares: middleware.Object);
return new(adapter, factory, queue, logger);
}

Expand All @@ -241,9 +241,8 @@ private class TestAdapter(
IChannelServiceClientFactory channelServiceClientFactory,
IActivityTaskQueue activityTaskQueue,
ILogger<IBotHttpAdapter> logger = null,
bool async = true,
params Core.Interfaces.IMiddleware[] middlewares)
: CloudAdapter(channelServiceClientFactory, activityTaskQueue, logger, async, middlewares)
: CloudAdapter(channelServiceClientFactory, activityTaskQueue, logger, null, middlewares)
{
public override Task<InvokeResponse> ProcessActivityAsync(ClaimsIdentity claimsIdentity, IActivity activity, BotCallbackHandler callback, CancellationToken cancellationToken)
{
Expand Down

0 comments on commit 8e22337

Please sign in to comment.