All Projects → icsharp → Hangfire.topshelf

icsharp / Hangfire.topshelf

Licence: mit
Best practice for hangfire samples

Projects that are alternatives of or similar to Hangfire.topshelf

Rxmq.js
JavaScript pub/sub library based on RxJS
Stars: ✭ 134 (-30.21%)
Mutual labels:  message-queue, message-bus
Schedex
Simple scheduling for Elixir
Stars: ✭ 173 (-9.9%)
Mutual labels:  scheduled-jobs, scheduled-tasks
OpenSleigh
OpenSleigh is a Saga management library for .NET Core.
Stars: ✭ 198 (+3.13%)
Mutual labels:  message-bus, message-queue
psr-container-messenger
Message bus and queue for Mezzio with Symfony Messenger + Enqueue
Stars: ✭ 24 (-87.5%)
Mutual labels:  message-bus, message-queue
Message Bus
Go simple async message bus
Stars: ✭ 166 (-13.54%)
Mutual labels:  message-queue, message-bus
telephone-ts
Telephone-ts: The "Event Emitter-less" TypeScript Event Architecture.
Stars: ✭ 22 (-88.54%)
Mutual labels:  message-bus, message-queue
Quartznet
Quartz Enterprise Scheduler .NET
Stars: ✭ 4,825 (+2413.02%)
Mutual labels:  scheduled-jobs, scheduled-tasks
Nats.c
A C client for NATS
Stars: ✭ 220 (+14.58%)
Mutual labels:  message-queue, message-bus
Nats Server
High-Performance server for NATS.io, the cloud and edge native messaging system.
Stars: ✭ 10,223 (+5224.48%)
Mutual labels:  message-queue, message-bus
Frame Scheduling
Asynchronous non-blocking running many tasks in JavaScript. Demo https://codesandbox.io/s/admiring-ride-jdoq0
Stars: ✭ 64 (-66.67%)
Mutual labels:  scheduled-jobs, scheduled-tasks
grails-rabbitmq-native
A Grails plugin that provides convenient RabbitMQ functionality using the native Java library for RabbitMQ.
Stars: ✭ 27 (-85.94%)
Mutual labels:  message-bus, message-queue
Rebus
🚌 Simple and lean service bus implementation for .NET
Stars: ✭ 1,733 (+802.6%)
Mutual labels:  message-queue, message-bus
go-nats-examples
Single repository for go-nats example code. This includes all documentation examples and any common message pattern examples.
Stars: ✭ 99 (-48.44%)
Mutual labels:  message-bus, message-queue
Node Cron
A simple cron-like job scheduler for Node.js
Stars: ✭ 2,064 (+975%)
Mutual labels:  scheduled-jobs, scheduled-tasks
Enqueue Bundle
[READ-ONLY] Message queue bundle for Symfony. RabbitMQ, Amazon SQS, Redis, Service bus, Async events, RPC over MQ and a lot more
Stars: ✭ 233 (+21.35%)
Mutual labels:  message-queue, message-bus
Benthos
Fancy stream processing made operationally mundane
Stars: ✭ 3,705 (+1829.69%)
Mutual labels:  message-queue, message-bus
Qmq
QMQ是去哪儿网内部广泛使用的消息中间件,自2012年诞生以来在去哪儿网所有业务场景中广泛的应用,包括跟交易息息相关的订单场景; 也包括报价搜索等高吞吐量场景。
Stars: ✭ 2,420 (+1160.42%)
Mutual labels:  message-queue, message-bus
Phpnats
A PHP client for the NATSio cloud messaging system.
Stars: ✭ 209 (+8.85%)
Mutual labels:  message-queue, message-bus
Plumber
A swiss army knife CLI tool for interacting with Kafka, RabbitMQ and other messaging systems.
Stars: ✭ 514 (+167.71%)
Mutual labels:  message-queue, message-bus
Mq
MQ is a simple distributed in-memory message broker
Stars: ✭ 114 (-40.62%)
Mutual labels:  message-queue, message-bus

Hangfire.Topshelf

Build status

To initialize this repo, you need to run git command git submodule update --init --recursive after you clone the master repo.

Samples as below:

Host Hangfire server in windows service using Topshelf

  • Impl interface ServiceControl based on OWIN.
/// <summary>
/// OWIN host
/// </summary>
public class Bootstrap : ServiceControl
{
    private readonly LogWriter _logger = HostLogger.Get(typeof(Bootstrap));
    private IDisposable webApp;
    public string Address { get; set; }
    public bool Start(HostControl hostControl)
    {
        try
        {
            webApp = WebApp.Start<Startup>(Address);
            return true;
        }
        catch (Exception ex)
        {
            _logger.Error($"Topshelf starting occured errors:{ex.ToString()}");
            return false;
        }

    }

    public bool Stop(HostControl hostControl)
    {
        try
        {
            webApp?.Dispose();
            return true;
        }
        catch (Exception ex)
        {
            _logger.Error($"Topshelf stopping occured errors:{ex.ToString()}");
            return false;
        }

    }
}
  • Extension method UseOwin
public static HostConfigurator UseOwin(this HostConfigurator configurator, string baseAddress)
{
    if (string.IsNullOrEmpty(baseAddress)) throw new ArgumentNullException(nameof(baseAddress));

    configurator.Service(() => new Bootstrap { Address = baseAddress });

    return configurator;
}
  • Start windows service
static int Main(string[] args)
{
    log4net.Config.XmlConfigurator.Configure();

    return (int)HostFactory.Run(x =>
    {
        x.RunAsLocalSystem();

        x.SetServiceName(HangfireSettings.ServiceName);
        x.SetDisplayName(HangfireSettings.ServiceDisplayName);
        x.SetDescription(HangfireSettings.ServiceDescription);

        x.UseOwin(baseAddress: HangfireSettings.ServiceAddress);

        x.SetStartTimeout(TimeSpan.FromMinutes(5));
        //https://github.com/Topshelf/Topshelf/issues/165
        x.SetStopTimeout(TimeSpan.FromMinutes(35));

        x.EnableServiceRecovery(r => { r.RestartService(1); });
    });
}

Using IoC with Autofac

  • Register components using Autofac.Module
/// <summary>
/// Hangfire Module
/// </summary>
public class HangfireModule : Autofac.Module
{
    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        base.AttachToComponentRegistration(componentRegistry, registration);

        // Handle constructor parameters.
        registration.Preparing += OnComponentPreparing;

        // Handle properties.
        registration.Activated += (sender, e) => InjectLoggerProperties(e.Instance);
    }

    private void InjectLoggerProperties(object instance)
    {
        var instanceType = instance.GetType();

        // Get all the injectable properties to set.
        // If you wanted to ensure the properties were only UNSET properties,
        // here's where you'd do it.
        var properties = instanceType
            .GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => p.PropertyType == typeof(ILog) && p.CanWrite && p.GetIndexParameters().Length == 0);

        // Set the properties located.
        foreach (var propToSet in properties)
        {
            propToSet.SetValue(instance, LogProvider.GetLogger(instanceType), null);
        }
    }

    private void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        e.Parameters = e.Parameters.Union(new[]
                {
                new ResolvedParameter(
                    (p, i) => p.ParameterType == typeof(ILog),
                    (p, i) => LogProvider.GetLogger(p.Member.DeclaringType)
                ),
                });
    }

    /// <summary>
    /// Auto register
    /// </summary>
    /// <param name="builder"></param>
    protected override void Load(ContainerBuilder builder)
    {
        //register all implemented interfaces
        builder.RegisterAssemblyTypes(ThisAssembly)
            .Where(t => typeof(IDependency).IsAssignableFrom(t) && t != typeof(IDependency) && !t.IsInterface)
            .AsImplementedInterfaces();

        //register speicified types here
        builder.Register(x => new RecurringJobService());
    }
}
  • Extension method UseAutofac
public static IContainer UseAutofac(this IAppBuilder app, HttpConfiguration config)
{
    if (config == null) throw new ArgumentNullException(nameof(config));

    var builder = new ContainerBuilder();

    var assembly = typeof(Startup).Assembly;

    builder.RegisterAssemblyModules(assembly);

    builder.RegisterApiControllers(assembly);

    var container = builder.Build();

    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

    GlobalConfiguration.Configuration.UseAutofacActivator(container);

    return container;
}

Register RecurringJob automatically

  • Usage
public class RecurringJobService
{
    [RecurringJob("*/1 * * * *")]
    [DisplayName("InstanceTestJob")]
    [Queue("jobs")]
    public void InstanceTestJob(PerformContext context)
    {
        context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} InstanceTestJob Running ...");
    }

    [RecurringJob("*/5 * * * *")]
    [DisplayName("JobStaticTest")]
    [Queue("jobs")]
    public static void StaticTestJob(PerformContext context)
    {
        context.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} StaticTestJob Running ...");
    }
}

public interface ISampleService : IAppService
{
    /// <summary>
    /// simple job test
    /// </summary>
    /// <param name="context"></param>
    [RecurringJob("0 4 1 * *")]
    [AutomaticRetry(Attempts = 3)]
    [DisplayName("SimpleJobTest")]
    [Queue("jobs")]
    void SimpleJob(PerformContext context);
}

In app start, using extension method UseRecurringJob to assign the types targeted by RecurringJobAttribute:

GlobalConfiguration.Configuration.UseRecurringJob(typeof(RecurringJobService), typeof(ISampleService))

Architecture

Monolithic

Monolithic

Cluster

Cluster

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].