Is there an in memory job storage package for Hangfire?
Asked Answered
O

5

46

I have a console application to test HangFire. Here is the code:

using System;
using Hangfire;

namespace MyScheduler.ConsoleApp
{
    internal static class Program
    {
        internal static void Main(string[] args)
        {
            MyMethod();

            Console.WriteLine("[Finished]");
            Console.ReadKey();
        }

        private static void MyMethod()
        {
            RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), Cron.Minutely);
        }
    }
}

But it throws an exception on runtime:

Additional information: JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.

So I need a job storage to run this. But all examples in SQL storage etc. Is there any way to run this example with some kind of memory storage?

JobStorage.Current = new SqlServerStorage("ConnectionStringName", options);  
// to  
JobStorage.Current = new MemoryDbStorage(string.Empty, options);  
Oriya answered 4/4, 2017 at 12:4 Comment(6)
Did you try doing a Google search for "Hangfire memory"? I found the answer to your question in under 10 seconds. And even if you decide that doesn't work for you, there's plenty of other options that are easy to set up such as SQL Server LocalDB, SQLite, and Mongo.Lillielilliputian
I updated my question. And documention should be updated too. Have a nice day.Oriya
NuGet's search feature isn't so good. Use Google/Bing. Anyways, there's no need to tell us about the documentation. You can submit a pull request to update it or raise an issue on their GitHub. Anyways, I think their documentation there is fine. If you read it, "Hangfire.Core is enough" is clearly referring to not installing the main "Hangfire" package which has dependencies not needed by a console app. And right above that it clearly states you need a job storage package. It's pretty clear to me.Lillielilliputian
I didn't edit your answer. You don't have an answer! You have a question. Questions posts are for questions, answer posts are for answers. That's just how we try to keep things clean on Stack Overflow. What you had edited into your question wasn't part of the question (and wasn't an solution either), just some thoughts that fit better into a comment. That's why I edited it out - to keep your question clean and focused on the issue.Lillielilliputian
I did read the documentation you linked to - I've read over that page myself a few times, having used Hangfire in several projects. The documentation is clear enough to me. It states use Hangfire.Core, not Hangfire. And it states you need a job storage package. That's straightforward enough. But if you disagree, Stack Overflow is not the place to vent your disagreement. If you want the documentation updated, then you can either do it yourself or request that someone do it by filing an issue on their GitHub repo. Stating "someone should update it" here is just noise. Focus on the issue!Lillielilliputian
I see you've edited that text back into your question, even after my explanation. Rather than me unilaterally reverting it, perhaps you should state why you think it belongs in your question?Lillielilliputian
P
68

You can use Hangfire.MemoryStorage for this.

Simply add this nuget package.

And then you can use it like -

GlobalConfiguration.Configuration.UseMemoryStorage();
Pussy answered 4/4, 2017 at 12:17 Comment(6)
@mason: Yup, heard that :), but just in case..., may be he got confused or kind of, i dont know. but he posted the q., which is more effort than a google search, so i thought probably he needed answer from us :)Pussy
As the author notices, memory storage is not supposed to be in a production environment.Alkane
I want to utilize Hangfire for a continuous background job, and I don't want to store anything anywhere. I have my own logs. I don't want the in memory storage either, because my app is memory sensitive. What options do I have?Semang
@VinShahrdar - This is not possible with HF, because HF by design require storage. Having said that, you can make HF runs as a separate application, so it will not affect your main app.Pussy
@Pussy I cannot use it as a separate app. I know it goes against the best practices, but my requirement is to spin up a single thread upon application initialization, and in this thread, I want to do a continuous file sync between a source and a destination. You think I should go with just a simple threading code?Semang
@VinShahrdar, yeah in case you may use Task Parallel Library (TPL). (learn.microsoft.com/en-us/dotnet/standard/parallel-programming/…)Pussy
P
41

For NET Core (web application):

Just to make it very obvious because it wasn't obvious to me.

Install following nuget packages:

  • Hangfire.AspNetCore (v1.6.17 atow)
  • Hangfire.MemoryStorage.Core (v1.4.0 atow)

In Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        // other registered services
        ...

        services.AddHangfire(c => c.UseMemoryStorage());
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // other pipeline configuration            
        ...

        app.UseHangfireServer();

        app.UseMvc();
    }

Anything less than above and my enqueued method did not fire.

Passenger answered 27/10, 2017 at 9:20 Comment(1)
And to make it super-duper obvious: don't forget the using Hangfire and using Hangfire.MemoryStorage declarations.Assembly
O
9

Just for the sake of completeness the author of the Hangfire library has added a new package titled Hangfire.InMemory the version of which is available on Nuget. The repository readme positions it as targeting production use. A quote github repo URL is as follows "..an efficient transactional in-memory storage for Hangfire with data structures close to their optimal representation. The result of this attempt should enable production-ready usage of this storage implementation and handle particular properties of in-memory processing.."

The familiar configuration concept applies here as well: GlobalConfiguration.Configuration.UseInMemoryStorage();

I personally added it as follows: services.AddHangfire(configuration => { configuration.UseInMemoryStorage(); });

Orly answered 25/1, 2021 at 18:45 Comment(1)
Is it possible to use both SQL and InMemory at the same time?Arun
K
6

As Yogi said, you can use Hangfire.MemoryStorage or Hangfire.MemoryStorage.Core (for .Net Core).

What is missing in that answer is the complete code (for .Net Core) that needs to be put inside ConfigureServices(..) :

var inMemory = GlobalConfiguration.Configuration.UseMemoryStorage();
services.AddHangfire(x => x.UseStorage(inMemory));
Kolva answered 3/8, 2017 at 3:43 Comment(0)
R
0

For in-memory with a .NET 6 console app (as a Windows Service), I use the following which also has the dashboard configured, should you wish to use it:

using Hangfire;
using Hangfire.Services;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

await Host
    .CreateDefaultBuilder()
    .ConfigureWebHostDefaults(builder =>
    {
        builder.Configure(app =>
        {
            app.UseHangfireDashboard();

            RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), Cron.Minutely);
        });
    })
    .UseWindowsService()
    .ConfigureServices(services =>
    {
        services.AddHangfire(opt =>
        {
            opt.UseInMemoryStorage();
        });

        services.AddHangfireServer();
    })
    .Build()
    .RunAsync();

This is using the official package from Hangfire - https://github.com/HangfireIO/Hangfire.InMemory

Rowell answered 25/8, 2023 at 9:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.