-
-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
updated service bus with new microsoft.azure.servicebus dotnet library #1
updated service bus with new microsoft.azure.servicebus dotnet library #1
Conversation
shahbarkha
commented
Aug 14, 2017
•
edited
Loading
edited
- First cut that allows the foundatio.azureservicebus to use the latest azure service bus dotnet library ( 1.0.0)
- Added 2 sample apps for topics and queues
…y version to 1.0.0 from 0.0.7 preview
…oreapp, and added few new options to the azuremessagebusoptions.
…e user does not provide any subscription name then by default guid is generated and topic is used with fanout mode
… library. putting the comment for the github issue.
…onasync, completeasync on different objects bases on the push or pull strategy.
…exception. We instead call the overloaded method with no timeout in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shahbarkha hope it helps
|
||
|
||
try { | ||
var o = new Receiver(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"o"? 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can now do static async Task MainAsync
and remove the Getawaiter().GetResult(). As this was added in the latest .net core..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also async Task Main()
🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good tip Blake. I just realized i have removed the reference of sample project from the solution but didnt delete the sample files from the repo. Will be deleting all the samples. I think our unit test cases are great enough to test all the possible scenarios
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
// General Information about an assembly is controlled through the following |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove commented out lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to drop all assembly info's as well or at least just provide a title and description as we do in the Foundatio Project (logging branch)
@@ -0,0 +1,26 @@ | |||
<?xml version="1.0" encoding="utf-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably don't need this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to remove the app.config completely in all projects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have actually deleted the sample project itself. I didn't find any value to that when we have good amount of unit test cases covering all the test cases.
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /> | ||
</startup> | ||
<runtime> | ||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be replaced entirely with
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
@@ -0,0 +1,83 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be entirely replaced by PackageReference
in csproj.
The benefit is you can reduce number of transitive packages listed as dependencies.
E.g.: xunit
has a dependency on xunit.assert
and xunit.core
which do not need to be referenced if using PackageReference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we switch to the new project system I don't think we can remove most of these references. We can do this in a second pr as well.
private async Task OnMessageAsync(BrokeredMessage brokeredMessage) { | ||
// Use this Handler to look at the exceptions received on the MessagePump | ||
private Task OnExceptionAsync(ExceptionReceivedEventArgs args) { | ||
_logger.Warn(args.Exception, "Message handler encountered an exception."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not swallow args
. It contains valuable information valuable information such as
- action that failed
- entity path
- namespace
It all should be logged imo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, We upgraded to the new Microsoft logging in foundatio 6. I can pair on this if you'd like
if (_subscribers.IsEmpty) | ||
return; | ||
|
||
_logger.Trace("OnMessageAsync({messageId})", brokeredMessage.MessageId); | ||
_logger.Trace($"Received message: messageId:{ brokeredMessage.MessageId} SequenceNumber:{brokeredMessage.SystemProperties.SequenceNumber}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MessageId
can be null
. You want to wrap it with some sort of delimiters to avoid confusion in the output.
Eg: $"Received message: messageId:'{brokeredMessage.MessageId}' SequenceNumber....
if (!String.IsNullOrEmpty(_options.TopicUserMetadata)) | ||
td.UserMetadata = _options.TopicUserMetadata; | ||
//if (!String.IsNullOrEmpty(_options.TopicUserMetadata)) | ||
// td.UserMetadata = _options.TopicUserMetadata; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If disabled because of issues in GH (like this one), ideally would be good to see the issue URL in a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shahbarkha Azure/azure-sdk-for-net#3635 Any idea if this is now supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@niemyjski Its still not supported!!
); | ||
|
||
// If the token isn't a valid string, throw an error. | ||
if (String.IsNullOrEmpty(result.AccessToken)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String.IsNullOrEmpty
should be
string.IsNullOrEmpty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SeanFeldman Thanks Sean for reviewing this. I know I am asking for too much but can you please also take a glance at the functionality on how I am calling AbandonAsync, CompleteAsync using 2 different objects ( IQueueclient and IMessageReceiver )
await _queueClient.CompleteAsync(entry.Id).AnyContext();
await _messageReceiver.CompleteAsync(entry.Id).AnyContext();
As you noticed this library has 2 ways of pulling the items from the queue:
- Push Strategy - Which IQueueClient provides by registering RegisterMessageHandler.
- Pull Strategy - Which IMessageReceive provides using ReceiveAsync.
For some reason, in the new azure service bus dot net core library ReceiveAsync method has been removed from the IQueueClient and that leaves me to use the IMessageReceiver for fetching the item from the queue for the 2nd strategy.
Even though the endpoint for the queue is same if I try to call AbandonAsyc using the IMessageReceiver object for the queue item that has been dequeued using IQueueClient, I get "MessageLockLostException". Similary, If i try to call AbandonAsync using the IQueueClient object for the queue item that has been dequeued using IMessageReceiver, then also i get the same exception.
Because of this reason, I have to maintain some metadata in the QueueEntry to know if the queue item was dequeued using push or pull strategy so that I can call the AbandonAsync or CompleteAsync and even RenewLockAsync using appropriate objects ( either IQueueClient or IMessageReceiver ).
Do you know by any chance why there is a difference in behavior ? Shouldnt there be no exception if i try to call any of the above methods with any object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The older version of the library used SBMP by default. The new one is using AMQP. With SBMP you could receive a message with one receiver and complete with another where with AMQP there's a receiver affinity. Meaning you have to complete/abandon/renew your message using the same receiver used to get the message to begin with.
As for the MessageAPI (registering message handler) and ReceiveAsync
, it's all there, just slightly reshuffled. ReceiveAsync
is now on MessageReceiver
as it's considered a more "advanced" option (you control number of messages, write your own message pump, etc) and QueueClient
is more of a "simple" scenario, intended to be used with the OOTB message pump registered with RegisterSessionHandler
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AMQP there's a receiver affinity.
Is that for AMQP in general?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the ASB .NET Standard client. Don't know if that's a general AMQP requirement or not.
No Blake it’s not implemented yet in the new 2.0 version
Thank you
Sent from my iPhone - Barkha shah
… On Oct 30, 2017, at 7:47 AM, Blake Niemyjski ***@***.***> wrote:
@niemyjski commented on this pull request.
In src/Foundatio.AzureServiceBus/Messaging/AzureServiceBusMessageBus.cs:
> @@ -151,14 +204,14 @@ public class AzureServiceBusMessageBus : MessageBusBase<AzureServiceBusMessageBu
if (_options.TopicEnableExpress.HasValue)
td.EnableExpress = _options.TopicEnableExpress.Value;
- if (!String.IsNullOrEmpty(_options.TopicUserMetadata))
- td.UserMetadata = _options.TopicUserMetadata;
+ //if (!String.IsNullOrEmpty(_options.TopicUserMetadata))
+ // td.UserMetadata = _options.TopicUserMetadata;
@shahbarkha Azure/azure-sdk-for-net#3635 Any idea if this is now supported?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, There are some small things that need to be updated like the tests calling the wrong methods and I'm not sure if a queue instance is being returned. I know some of that is timeout related and we probably need to address that in the base test harness (making a timeout passed in, or we correct the min timespan passed in to us to be the min azure allowed timespan if 0 is passed). It looks like the foundatio lib needs to be updated to the latest version (6.0). I can help with that if you think it's good to be merged in. We could merge it to a branch and then rework logging and the configuration system.
@@ -0,0 +1,26 @@ | |||
<?xml version="1.0" encoding="utf-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to remove the app.config completely in all projects
<None Include="packages.config" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Foundatio.TestHarness" Version="5.1.1474" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should pull in Foundatio 6.0. We just need to add the following nuget config (https://github.com/FoundatioFx/Foundatio.Redis/blob/feature/logging/NuGet.config minus the loresoft on line 5)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed the sample projects. Now I am referencing Foundatio 5.1.1562 which is the latest and the greatest. I dont see 6.0 in the Updates at all. Am I missing something
|
||
|
||
try { | ||
var o = new Receiver(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can now do static async Task MainAsync
and remove the Getawaiter().GetResult(). As this was added in the latest .net core..
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
// General Information about an assembly is controlled through the following |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to drop all assembly info's as well or at least just provide a title and description as we do in the Foundatio Project (logging branch)
class Receiver { | ||
private async Task TestTopic() { | ||
IMessageBus messageBus = | ||
new AzureServiceBusMessageBus(new AzureServiceBusMessageBusOptions() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we update to the latest foundatio 6, it brings in the logging changes and we've migrated everything to the new cross plat configuration system). We can accept the pr as is but if you wanted to tackle that it's pretty fun to play with and learn :)
if (_topicClient == null) | ||
return; | ||
|
||
_topicClient?.Close(); | ||
await _topicClient?.CloseAsync(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to ensure we have AnyContext() on all awaited async methods.
LoggerFactory = Log | ||
}); | ||
} | ||
//protected override IQueue<SimpleWorkItem> GetQueue(int retries = 0, TimeSpan? workItemTimeout = null, TimeSpan? retryDelay = null, int deadLetterMaxItems = 100, bool runQueueMaintenance = true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these tests even running since there is no Queue implementation being returned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes they are all running with actual Queue parameters. They are commented out because they need to be supplied with the actual values mentioned in the configuration file. Once they are supplied all tests pass. If they are commented then the base queue implementation is returned. One needs to uncomment them for all the ASB specific tests to run.
[Fact] | ||
public override Task WillWaitForItemAsync() { | ||
return base.WillWaitForItemAsync(); | ||
return WillWaitItemAsync(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is calling the wrong test method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to override the method because base class has some timeout values which does not work for ASB. Like you mentioned we need to supply min and max timeout value.
public override Task WillNotWaitForItemAsync() { | ||
return base.WillNotWaitForItemAsync(); | ||
return DontWaitForItemAsync(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is calling the wrong test method
public override Task CanRenewLockAsync() { | ||
return base.CanRenewLockAsync(); | ||
return RenewLockAsync(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is calling the wrong test method
-Added base project for benchmark. Still need to write code. -Removed the files from the Sample project.
- Using Microsoft.Extensions.Logging for logging - Fixed unit test for service message bus
@@ -73,44 +71,34 @@ public class AzureServiceBusMessageBus : MessageBusBase<AzureServiceBusMessageBu | |||
|
|||
_subscriptionClient.RegisterMessageHandler(OnMessageAsync, new MessageHandlerOptions(OnExceptionAsync) { MaxConcurrentCalls = maxConcurrentCalls, AutoComplete = autoComplete }); | |||
sw.Stop(); | |||
_logger.Trace("Ensure topic subscription exists took {0}ms.", sw.ElapsedMilliseconds); | |||
if (_logger.IsEnabled(LogLevel.Trace)) _logger.LogTrace("Ensure topic subscription exists took {ElapsedMilliseconds}", sw.ElapsedMilliseconds); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, I learned yesterday that if you do "{Duration:g}", sw.Elapsed
you get really nice formatting for timespans :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will make these changes. Thank you
_queueClient.RegisterMessageHandler(async (msg, token) => { | ||
_logger.Trace("WorkerLoop Signaled {_options.Name}", _options.Name); | ||
if (_logger.IsEnabled(LogLevel.Trace)) _logger.LogTrace("WorkerLoop Signaled {.Name}", _options.Name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We got an extra . in here by accident
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -165,7 +170,7 @@ public class AzureServiceBusQueueTests : QueueTestBase { | |||
var sw = Stopwatch.StartNew(); | |||
var workItem = await queue.DequeueAsync(TimeSpan.FromMilliseconds(100)); | |||
sw.Stop(); | |||
_logger.Trace("Time {0}", sw.Elapsed); | |||
if (_logger.IsEnabled(LogLevel.Trace)) _logger.LogTrace("Time {Elapsed}", sw.Elapsed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add the formatter for Elapsed to {Duration:g}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!!!!
Looks great!! Awesome job. Do you feel like we should merge it in or merge it into a branch? Guess we could merge it in and just bump the major again or put it in preview until the management stuff gets done |
@SeanFeldman would you mind reviewing this and leaving your comments to my last question :) Thanks in advance |
Let me know when you want me to merge this in :) |
@niemyjski I liked your idea of putting this stuff on the preview untill the management stuff is released. Also I want to do the benchmark thing going on before we merge it in the master. |
Thanks for the PR! I've merged this into the .net standard branch. We'll push a preview build out shortly. We might have to wait until the logging release goes out as that's going to be a stable build and then this one so it's a higher nightly preview build or bump the major on this |
Sorry @niemyjski, was away on vacation. Looks like a bit late to review 😃 |