Category Archive News

ByMogens

Rebus’ Azure Service Bus transport now supports .NET Core

For almost a year, this GitHub issue has been open – but I’m happy to announce that I’ve closed it just now, which I’ve done of course because Rebus’ Azure Service Bus transport has now finally been ported properly to Microsoft’s new Azure Service Bus driver.

When the new driver came out, lots of people were puzzled, because it lacked the management operations from the original driver. This meant that queue creation, topic creation, and even mundane stuff like subscribing to topics, could not be done with it.

It took a long time and some pretty dedicated community work for the driver to come out with management operations in it, which happened about two months ago (as a prerelease, stable version was out one month ago).

Today, all of our Fleet Manager environments have been running with Rebus’ new Azure Service Bus transport a week or more, so we’re ready to let Rebus.AzureServiceBus 6.0.0 out into the wild 🦁🌳which in turn means that Rebus can use Azure Service Bus on the .NET Core 2.0/.NET 4.6.1 and later runtimes.

ByMogens

Another neat little library: MongolianBarbecue

The process of building larger software projects holds many small opportunities for separating out small utilities and helper libraries, and one such opportunity has again arisen 🙂

This time it’s a message queue implementation based on MongoDB: MongolianBarbecue (sounds a little bit like something with “mongo” and “queue”…. 🤓)

It’s of course not meant to be able to replace real message brokers and queueing systems, but if you’re in a tight spot, and all you have is MongoDB, then it might just save the day! 🤠

Using it is easy – you can configure it like this:

var config = new Config(
    connectionString: "mongodb://MONGOBONGO01/Readme", 
    collectionName: "messages"
);

and then you send a message to a queue named my-queue like this:

var producer = config.CreateProducer();

var payload = Encoding.UTF8.GetBytes("Hej med dig, min ven!");
var message = new Message(payload);

await producer.SendAsync("my-queue", message);

When it’s time to receive a message, you create a consumer for a specific queue like this:

var consumer = config.CreateConsumer("my-queue");

and then you get the next message like this:

var messageOrNull = await consumer.GetNextAsync();

// do stuff with the message if it's not null

MongolianBarbecue uses lease-based locking of messages, so it’s safe to use in any kind of distributed scenario you can come up with (e.g. like competing consumers). Moreover, it is pretty easy to use it to implement distributed locking, which can be used to implement exclusive access to a distributed resource.

Neat! 😎

ByMogens

Tababular update

This is just a tiny update about the nifty little library that is Tababular, because I enjoy using it so much, and I think more people should be using it too 🙂

The latest prerelease (3.0.0-b02) adds .NET Standard 2.0 as a target, and it has had a make-over making it appear more spacey, and therefore easier to decode visually:

+-------------+--------------+-------------+
| FirstColumn | SecondColumn | ThirdColumn |
+-------------+--------------+-------------+
| r1          | hej          | hej igen    |
+-------------+--------------+-------------+
| r2          | hej          | hej igen    |
+-------------+--------------+-------------+

Last but not least, it has had its reflection routines implemented using the brilliant FastMember library, thus making it easier on your CPU 😊

ByMogens

Fleet Manager 2 is out

So… we’ve been pretty busy here at Rebus FM, building the 2nd incarnation of our Fleet Manager product (which is actually the 5th or the 7th rewrite of the frontend, depending on how you count it… but who cares?!).

We celebrated Labour Day by working even harder, which means that it’s available now! We just call it Version 2, but if you have been using the old Fleet Manager, you can probably see that it looks a little different:

It has seen numerous improvements – too many to mention, really – so I suggest you go check out some screenshots on the updated Fleet Manager page, or just go to https://manager.rebus.fm if you’re already a customer.

ByMogens

Fleet Manager screenshots

To whet your appetite as a Rebus user, who is eager to one-up your game, I have posted a bunch of screenshots here on the Fleet Manager page.

While Fleet Manager is still in development and is nowhere near finished yet, it can still be quite useful to provide an overview over what is running and what is not.

If you are interested in getting access, please go consider the Rebus Pro offering – it includes a 24h support agreement in addition to instant cloud-hosted Fleet Manager access.

ByMogens

Rebus Pro

It took a couple of iterations to figure this out, but finally it has become clear which shape the commercial Rebus offering is going to take.

Say hello to REBUS PRO! 🙂

Rebus Pro is

  • Fleet Manager (either cloud-hosted SaaS or on-prem BYOH*)
  • 24h support agreement
  • Access to private Slack channel

accessible by subscription (monthly, with savings for 3 or 6 months commitment).

Please shoot an email to [email protected] if you are interested in hearing more 🙂


(*) Bring Your Own Hardware 😉

ByMogens

Rebus 4 is out!

It only took 23 beta versions to get there 🙂

The cool thing about Rebus 4 is that it targets both .NET 4.5 and .NET Standard 1.3, making it possible to run Rebus endpoints on all server platforms that matter. In fact, I know of people who at this point have been running quite a lot of Rebus on AWS… On Linux! In Docker containers!

Most integration packages have been updated too, and almost all of them are supported on .NET Core as well, so you should go ahead and try it out.

Notable exceptions at this moment are Rebus.Msmq and Rebus.AzureServiceBus

MSMQ is not supported by any .NET Standard version, so it’s quite obvious why the 4.0.0 version of that package still only targets .NET 4.5.

Azure Service Bus is supported on .NET Core now though, but it has been implemented in a completely new version of the driver that has a radically changed API and therefore requires a lot of work to update. Version 4.0.0 of Rebus.AzureServiceBus will therefore target .NET 4.5 only.

You may go Update-Packages Rebus now 🙂

ByMogens

Rebus and .NET Core

.NET Core is Microsoft’s new incarnation of .NET, where many things have been changed to be able to accommodate future needs for (primarily server side) application development. This is also the biggest change ever in the .NET world that is not backwards compatible!

For a long time we have had the ability to take an old .NET 2.0 DLL and plop it down next to our other DLLs, and then we would be able to use it right away. Because .NET Core is such a huge change (i.e. it uses a radically re-engineered runtime), that is no longer possible.

This puts a big burden on library developers (e.g. like me 🙂 ) who want to be prepared for the future, while supporting all of the old stuff still.

The good news is that with Visual Studio 2017 and the new CSPROJ format, it has actually become pretty straightforward to write libraries that target multiple frameworks by leveraging the <TargetFrameworks> element in the CSPROJ file (note the plural ‘s’ in there – when you create a new project, there is a <TargetFramework> element, but you need to add an ‘s’ if you put several targets in there).

By the power of open source and a persevering Rebus contributor, beta versions of Rebus 4 have now been released, targeting .NET 4.5 as always as well as .NETStandard 1.6 (which is .NET Core 1.0)

I am now in the process of porting all of the 40+ Rebus projects that it makes sense to port. You can follow the progress here. If you feel like messing a bit with .NET Core and becoming a Rebus contributor, feel free to get in touch and then we’ll figure out how you can help.

Exciting times ahead! 🙂

ByMogens

Check out Debaser

In case you are using Microsoft SQL Server, you may have tried writing a MERGE (...) statement…. did you think it was fun? 🙂

I think MERGE statements are not fun at all, but from time to time it IS necessary to execute a performant UPSERT-type of operation.

Maybe you also know that the fastest way to execute a huge number of upserts is to

  • create a custom table data type
  • create a stored procedure that executes the MERGE statement, using the data type as its input type
  • STREAM rows to the stored procedure via a table in tempdb

which can be pretty tedious to code.

Which is why the “upsert helper”, Debaser, was made 🙂

With Debaser, you can execute obscenely fast upserts by doing the following things:

Create a class that matches the layout of the table you want

E.g. something like

class SomeDataRow
{
    public SomeDataRow(int id, decimal number, string text)
    {
        Id = id;
        Number = number;
        Text = text;
    }

    public int Id { get; }
    public decimal Number { get; }
    public string Text { get; }
}

will do.

Initialize the upsert helper

This can be done like this:

var helper = new UpsertHelper<SomeDataRow>(connectionString);

and then you might want to

helper.CreateSchema();

when your application starts up. This will create a table, a custom table data type, and an appropriate stored procedure.

Upsert like crazy

Pass very very long sequences of row objects to the upsert helper like this:

await helper.Upsert(longLongSequence);

which is cool, because the upsert helper streams the data to SQL Server.

Pretty cool

If you think this looks cool, you should go to the Debaser wiki and read more about it, and maybe you want to Install-Package Debaser and start punishing your database right away?

Happy upserting!

ByMogens

Rebus 3 is out

Happy New Year!

This is just to let you know that Rebus 3 is out 🙂

The version was bumped to 3 because IAdvancedApi and IDataBus have been extended with more methods, and there are some changes around how to manually create transactions when sending messages outside of message handlers.

It is absolutely 100% wire-compatible with Rebus 2!

If you are interested in checking out which features were added, you can go to the tag comment and see the relevant bullets from the changelog. Most notable hightlights are a synchronous bus API (which can be accessed via bus.Advanced.SyncBus) and a few extra much needed methods on IDataBus.

Changes you need to make if you upgrade

If you are using DefaultTransactionContext

If you do this in your application:

using(var context = new DefaultTransactionContext())
{
    AmbientTransactionContext.Current = context;

    try
    {
        await bus.Publish(anEvent);

        await context.Complete();
    }
    finally
    {
        AmbientTransactionContext.Current = null
    }
}

you will have to change it to something like this:

using(var scope = new DefaultTransactionContextScope())
{
    await bus.Publish(anEvent);

    await scope.Complete();
}

which is much prettier and much much harder to mess up 🙂

If you implemented IDataBus or IAdvancedApi

…you will have to add two extra methods on IDataBus: Task<Stream> OpenRead(string dataBusAttachmentId); and Task<Dictionary<string, string>> GetMetadata(string dataBusAttachmentId); and one extra property on IAdvancedApi: ISyncBus SyncBus { get; }

If you implemented IDataBus or IAdvancedApi you most likely did it in order to decorate either service or to function as a test stub. Hopefully it will not be too cumbersome to extend those implementations to support the extra operations.

If you are using Rebus’ built-in logging

If you are using the GetCurrentClassLogger() method of IRebusLoggerFactory you will have to call GetLogger<YourClass>() instead – the stack frame walking turned out to be unreliable in some method inlining scenarios.

If you are using other Rebus packages

You will most likely have to update them to a version that is compiled against 3.0.0.