├── .gitignore
├── Agent
├── Hangfire.HttpJob.Agent.MssqlConsole
│ ├── Hangfire.HttpJob.Agent.MssqlConsole.csproj
│ ├── JobAgentMssqlConsoleCollectionExtensions.cs
│ ├── MssqlConsole.cs
│ ├── MssqlConsoleOptionsConfigurer.cs
│ ├── MssqlStorage.cs
│ └── MssqlStorageOptions.cs
├── Hangfire.HttpJob.Agent.MysqlLog
│ ├── Hangfire.HttpJob.Agent.MysqlConsole.csproj
│ ├── JobAgentConsoleCollectionExtensions.cs
│ ├── MySqlStorage.cs
│ ├── MySqlStorageOptions.cs
│ ├── MysqlConsole.cs
│ └── MysqlConsoleOptionsConfigurer.cs
├── Hangfire.HttpJob.Agent.PostgreSqlConsole
│ ├── Hangfire.HttpJob.Agent.PostgreSqlConsole.csproj
│ ├── JobAgentConsoleCollectionExtensions.cs
│ ├── PostgreSqlConsole.cs
│ ├── PostgreSqlConsoleOptionsConfigurer.cs
│ ├── PostgreSqlStorage.cs
│ └── PostgreSqlStorageOptions.cs
├── Hangfire.HttpJob.Agent.RedisConsole
│ ├── Hangfire.HttpJob.Agent.RedisConsole.csproj
│ ├── JobAgentConsoleCollectionExtensions.cs
│ ├── RedisConsole.cs
│ ├── RedisConsoleOptionsConfigurer.cs
│ ├── RedisStorage.cs
│ └── RedisStorageOptions.cs
├── Hangfire.HttpJob.Agent
│ ├── Attribute
│ │ ├── HangJobUntilStopAttribute.cs
│ │ ├── JobAttribute.cs
│ │ ├── SingletonJobAttribute.cs
│ │ └── TransientJobAttribute.cs
│ ├── Config
│ │ ├── ConfigureJobAgentConsoleOptions.cs
│ │ ├── ConfigureJobAgentOptions.cs
│ │ ├── JobAgentOptions.cs
│ │ ├── JobAgentOptionsConfigurer.cs
│ │ ├── JobAgentServiceConfigurer.cs
│ │ └── JobMetaData.cs
│ ├── Console
│ │ ├── ConsoleFontColor.cs
│ │ ├── ConsoleInfo.cs
│ │ ├── ConsoleLine.cs
│ │ ├── HangfireConsole.cs
│ │ ├── HangfireProgressBar.cs
│ │ ├── IHangfireConsole.cs
│ │ └── IStorageFactory.cs
│ ├── Hangfire.HttpJob.Agent.csproj
│ ├── Heartbeat.cs
│ ├── JobAgent.cs
│ ├── JobAgentApplicationBuilderExtensions.cs
│ ├── JobAgentMiddleware.cs
│ ├── JobAgentRegisterService.cs
│ ├── JobAgentServiceCollectionExtensions.cs
│ ├── JobContext.cs
│ ├── JobStatus.cs
│ └── Util
│ │ ├── AgentThreadPool.cs
│ │ ├── CodingUtil.cs
│ │ ├── EnumerableExtensions.cs
│ │ ├── LazyConcurrentDictionary.cs
│ │ ├── LoggerConsole.cs
│ │ └── ProgressEnumerable.cs
└── Template
│ ├── README.md
│ ├── Template.csproj
│ └── templates
│ └── Template
│ ├── .template.config
│ └── template.json
│ ├── Jobs
│ ├── TestHangJob.cs
│ ├── TestJob.cs
│ └── TestTransientJob.cs
│ ├── NLog.Config
│ ├── Program.cs
│ ├── Properties
│ └── launchSettings.json
│ ├── Startup.cs
│ ├── Template.csproj
│ ├── appsettings.Development.json
│ └── appsettings.json
├── Client
└── Hangfire.HttpJob.Client
│ ├── BackgroundJob.cs
│ ├── Hangfire.HttpJob.Client.csproj
│ ├── HangfireHttpClientFactory.cs
│ ├── HangfireJobClient.cs
│ ├── HangfireJobResult.cs
│ ├── HangfireServerPostOption.cs
│ ├── HttpJobItem.cs
│ └── RecurringJob.cs
├── Hangfire.HttpJob.sln
├── LICENSE.md
├── README.md
├── Server
└── Hangfire.HttpJob
│ ├── Content
│ ├── cron.js
│ ├── httpjob.js
│ ├── jsoneditor.css
│ ├── jsoneditor.js
│ ├── resx
│ │ ├── Strings.Designer.cs
│ │ ├── Strings.es.resx
│ │ ├── Strings.resx
│ │ ├── Strings.zh-TW.resx
│ │ └── Strings.zh.resx
│ ├── sweetalert2.min.css
│ └── sweetalert2.min.js
│ ├── Dashboard
│ ├── DynamicCssDispatcher.cs
│ ├── DynamicJsDispatcher.cs
│ ├── Heartbeat
│ │ └── Dashboard
│ │ │ ├── ContentDispatcher.cs
│ │ │ ├── OverviewPage.cs
│ │ │ ├── OverviewPageModel.cs
│ │ │ ├── UtilizationJsonDispatcher.cs
│ │ │ ├── css
│ │ │ └── styles.css
│ │ │ ├── html
│ │ │ └── OverviewPage.html
│ │ │ └── js
│ │ │ ├── OverviewPage.js
│ │ │ ├── knockout-3.4.2.js
│ │ │ ├── knockout.bindings.orderable.js
│ │ │ └── numeral.min.js
│ └── Pages
│ │ ├── CronJobsPage.cshtml
│ │ └── CronJobsPage.generated.cs
│ ├── GlobalConfigurationExtension.cs
│ ├── Hangfire.HttpJob.csproj
│ ├── HangfireHttpJobOptions.cs
│ ├── PageDto.cs
│ ├── Server
│ ├── HangfireHttpClientFactory.cs
│ ├── Heartbeat
│ │ ├── ConfigurationExtensions.cs
│ │ ├── HeartbeatDashboardOptions.cs
│ │ ├── HeartbeatProcessMonitorOptions.cs
│ │ ├── ProcessInfo.cs
│ │ ├── ProcessMonitor.cs
│ │ └── Utils.cs
│ ├── HttpJob.cs
│ ├── HttpJobDispatcher.cs
│ ├── HttpJobItem.cs
│ └── JobAgent
│ │ ├── JobAgentHeartBeatServer.cs
│ │ ├── JobAgentReportServer.cs
│ │ └── LosedJobCheckServer.cs
│ ├── Support
│ ├── AutomaticRetrySetAttribute.cs
│ ├── CodingUtil.cs
│ ├── CompositeDispatcher.cs
│ ├── EmailService.cs
│ ├── EmbeddedResourceDispatcher.cs
│ ├── ErrorState.cs
│ ├── HtmlHelperExtensions.cs
│ ├── HttpJobDisplayNameAttribute.cs
│ ├── HttpStatusCodeException.cs
│ ├── JobFilter.cs
│ ├── Models.cs
│ ├── ProcessingState.cs
│ ├── QueueProviderFilter.cs
│ ├── RouteCollectionExtensions.cs
│ └── UrlUtil.cs
│ └── TimeZoneInfoHelper.cs
├── Test
├── Hangfire.HttpJob.Client.Test
│ ├── Hangfire.HttpJob.Client.Test.csproj
│ └── UnitTest1.cs
├── MemoryHangfire
│ └── MemoryHangfire
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── HangfireCollectionExtensions.cs
│ │ ├── MemoryHangfire.csproj
│ │ ├── NLog.Config
│ │ ├── Program.cs
│ │ ├── Startup.cs
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.json
│ │ └── hangfire
│ │ └── hangfire_global.json
├── PostgreSqlHangfire
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── HangfireCollectionExtensions.cs
│ ├── NLog.Config
│ ├── PostgreSqlHangfire.csproj
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── hangfire
│ │ └── hangfire_global.json
├── RedisHangfire
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── HangfireCollectionExtensions.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── RedisHangfire.csproj
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── hangfire
│ │ └── hangfire_global.json
├── TestHangfire
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── HangfireCollectionExtensions.cs
│ ├── MysqlHangfire.csproj
│ ├── NLog.Config
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── hangfire
│ │ └── hangfire_global.json
├── TestHangfireAgent
│ ├── Jobs
│ │ ├── TestHangJob.cs
│ │ ├── TestJob.cs
│ │ └── TestTransientJob.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── TestHangfireAgent.csproj
│ └── appsettings.json
├── TestHangfirePostgreSqlAgent
│ ├── Jobs
│ │ ├── TestHangJob.cs
│ │ ├── TestJob.cs
│ │ └── TestTransientJob.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── TestHangfirePostgreSqlAgent.csproj
│ └── appsettings.json
├── TestHangfireRedisAgent
│ ├── Jobs
│ │ ├── TestHangJob.cs
│ │ ├── TestJob.cs
│ │ └── TestTransientJob.cs
│ ├── NLog.Config
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── TestHangfireRedisAgent.csproj
│ ├── appsettings.Development.json
│ └── appsettings.json
├── TestOwinHangfireRedisAgent
│ └── TestOwinHangfireRedisAgent
│ │ ├── App.config
│ │ ├── Jobs
│ │ ├── TestHangJob.cs
│ │ ├── TestJob.cs
│ │ └── TestTransientJob.cs
│ │ ├── NLog.Config
│ │ ├── Program.cs
│ │ ├── Properties
│ │ └── AssemblyInfo.cs
│ │ ├── Startup.cs
│ │ ├── TestOwinHangfireRedisAgent.csproj
│ │ ├── appsettings.Development.json
│ │ └── appsettings.json
├── TestSqlserver
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── HangfireCollectionExtensions.cs
│ ├── NLog.Config
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── SqlserverHangfire.csproj
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── hangfire
│ │ └── hangfire_global.json
└── TestSqlserverHangfireAgent
│ ├── Jobs
│ ├── TestHangJob.cs
│ ├── TestJob.cs
│ └── TestTransientJob.cs
│ ├── Program.cs
│ ├── Properties
│ └── launchSettings.json
│ ├── Startup.cs
│ ├── TestSqlserverHangfireAgent.csproj
│ └── appsettings.json
├── pic1.png
├── pic2.png
├── pic3.png
└── pic4.png
/.gitignore:
--------------------------------------------------------------------------------
1 | [Bb]in
2 | obj/
3 | *.suo
4 | *.user
5 | packages/
6 | .vs
7 | .idea/
8 | _ReSharper.Caches/
9 | Test/TestHangfire/AntDeploy.json
10 | Test/RedisHangfire/AntDeploy.json
11 | Test/TestSqlserver/AntDeploy.json
12 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.MssqlConsole/Hangfire.HttpJob.Agent.MssqlConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0;net461
5 | true
6 | true
7 | yuz
8 | yuzd
9 |
10 | https://github.com/yuzd/Hangfire.HttpJob
11 | agent job console to hangfire sqlserver
12 | 1.5.1
13 | MIT
14 | 1.5.1.0
15 | 1.5.1.0
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | TRACE;NETCORE
24 |
25 |
26 | TRACE;OWIN
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.MssqlConsole/MssqlConsole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.HttpJob.Agent.MssqlConsole
4 | {
5 | public class MssqlConsole : HangfireConsole
6 | {
7 | public MssqlConsole(IHangfireStorage storage)
8 | {
9 | Storage = storage ?? throw new ArgumentNullException(nameof(IHangfireStorage));
10 | }
11 |
12 | public override IHangfireStorage Storage { get; }
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.MssqlConsole/MssqlConsoleOptionsConfigurer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Hangfire.HttpJob.Agent.Config;
5 | using Microsoft.Extensions.Configuration;
6 | using Microsoft.Extensions.Options;
7 |
8 | namespace Hangfire.HttpJob.Agent.MssqlConsole.Config
9 | {
10 | public sealed class MssqlConsoleOptionsConfigurer : ConfigureJobAgentConsoleOptions
11 | {
12 | public MssqlConsoleOptionsConfigurer(IConfiguration configuration) : base(configuration)
13 | {
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.MssqlConsole/MssqlStorageOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.HttpJob.Agent.MssqlConsole
4 | {
5 | public class MssqlStorageOptions
6 | {
7 | public string HangfireDb { get; set; }
8 | public string TablePrefix { get; set; } = "HangFire";
9 |
10 | public int ExpireAtDays { get; set; } = 7;
11 |
12 | public TimeSpan? ExpireAt { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.MysqlLog/Hangfire.HttpJob.Agent.MysqlConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0;net461
5 | true
6 | true
7 | yuzd
8 | yuzd
9 |
10 | https://github.com/yuzd/Hangfire.HttpJob
11 | agent job console to hangfire mysql
12 | 1.4.8
13 | MIT
14 | 1.4.8.0
15 | 1.4.8.0
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | TRACE;NETCORE
25 |
26 |
27 | TRACE;OWIN
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.MysqlLog/MySqlStorageOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Hangfire.HttpJob.Agent.MysqlConsole
6 | {
7 | public class MySqlStorageOptions
8 | {
9 | public string TablePrefix { get; set; } = "hangfire";
10 | public string HangfireDb { get; set; }
11 | public int ExpireAtDays { get; set; } = 7;
12 | public TimeSpan? ExpireAt { get; set; }
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.MysqlLog/MysqlConsole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.HttpJob.Agent.MysqlConsole
4 | {
5 | internal class MysqlConsole : HangfireConsole
6 | {
7 | public MysqlConsole(IHangfireStorage storage)
8 | {
9 | Storage = storage ?? throw new ArgumentNullException(nameof(IHangfireStorage));
10 | }
11 |
12 | public override IHangfireStorage Storage { get; }
13 | }
14 |
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.MysqlLog/MysqlConsoleOptionsConfigurer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Hangfire.HttpJob.Agent.Config;
5 | using Microsoft.Extensions.Configuration;
6 | using Microsoft.Extensions.Options;
7 |
8 | namespace Hangfire.HttpJob.Agent.MysqlConsole.Config
9 | {
10 |
11 | public sealed class MysqlConsoleOptionsConfigurer : ConfigureJobAgentConsoleOptions
12 | {
13 | public MysqlConsoleOptionsConfigurer(IConfiguration configuration) : base(configuration)
14 | {
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.PostgreSqlConsole/Hangfire.HttpJob.Agent.PostgreSqlConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | netstandard2.0
12 | true
13 | zdyu
14 | agent job console to hangfire postgresql
15 | https://github.com/yuzd/Hangfire.HttpJob
16 | 1.4.8
17 | true
18 | zdyu
19 | MIT
20 | 1.4.8.0
21 | 1.4.8.0
22 |
23 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.PostgreSqlConsole/JobAgentConsoleCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Hangfire.HttpJob.Agent.Config;
3 | using Hangfire.HttpJob.Agent.PostgreSqlConsole.Config;
4 | using Microsoft.AspNetCore.Builder;
5 | using Microsoft.Extensions.DependencyInjection;
6 | using Microsoft.Extensions.DependencyInjection.Extensions;
7 | using Microsoft.Extensions.Logging;
8 | using Microsoft.Extensions.Options;
9 |
10 | namespace Hangfire.HttpJob.Agent.PostgreSqlConsole
11 | {
12 | public static class JobAgentConsoleCollectionExtensions
13 | {
14 | public static IServiceCollection AddHangfireJobAgent(this IServiceCollection services, Action configure = null)
15 | {
16 | services.AddHangfireHttpJobAgent(configure);
17 | services.AddJobAgentConsoleToPostgreSql();
18 | return services;
19 | }
20 |
21 | public static IApplicationBuilder UseHangfireJobAgent(this IApplicationBuilder app,
22 | Action configureOptions = null, Action configureStorageOptions = null)
23 | {
24 | app.UseHangfireHttpJobAgent(configureOptions);
25 | app.UseJobAgentConsoleToPostgreSql(configureStorageOptions);
26 | return app;
27 | }
28 |
29 | public static IServiceCollection AddJobAgentConsoleToPostgreSql(this IServiceCollection serviceCollection)
30 | {
31 | serviceCollection.AddOptions();
32 | serviceCollection.TryAddSingleton, PostgreSqlConsoleOptionsConfigurer>();
33 | serviceCollection.TryAddSingleton();
34 | serviceCollection.TryAddTransient();
35 | serviceCollection.TryAddTransient();
36 | return serviceCollection;
37 | }
38 |
39 | public static IApplicationBuilder UseJobAgentConsoleToPostgreSql(this IApplicationBuilder app,
40 | Action configureOptions = null)
41 | {
42 | var appServices = app.ApplicationServices;
43 | var evt = new EventId(1, "Hangfire.HttpJob.Agent.PostgreSqlConsole");
44 | var options = appServices.GetService>();
45 | var loggerFactory = appServices.GetService();
46 | var logger = loggerFactory.CreateLogger();
47 | try
48 | {
49 | configureOptions?.Invoke(options.Value);
50 | }
51 | catch (Exception exception)
52 | {
53 | logger.LogCritical(evt, exception, "【Hangfire.HttpJob.Agent.PostgreSqlConsole】 - Failed to configure Hangfire.HttpJob.Agent.PostgreSqlConsole middleware");
54 | }
55 |
56 | JobStorageConfig.LocalJobStorageConfig = new JobStorageConfig
57 | {
58 | Type = "postgresql",
59 | HangfireDb = options.Value?.HangfireDbConnString,
60 | TablePrefix = options.Value?.TablePrefix,
61 | ExpireAtDays = options.Value?.ExpireAtDays
62 | };
63 |
64 | logger.LogInformation(evt, "【Hangfire.HttpJob.Agent.PostgreSqlConsole】 - Registered PostgreSqlConsole middleware Success!");
65 | return app;
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.PostgreSqlConsole/PostgreSqlConsole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.HttpJob.Agent.PostgreSqlConsole
4 | {
5 | internal class PostgreSqlConsole : HangfireConsole
6 | {
7 | public PostgreSqlConsole(IHangfireStorage storage)
8 | {
9 | Storage = storage ?? throw new ArgumentNullException(nameof(IHangfireStorage));
10 | }
11 |
12 | public override IHangfireStorage Storage { get; }
13 | }
14 | }
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.PostgreSqlConsole/PostgreSqlConsoleOptionsConfigurer.cs:
--------------------------------------------------------------------------------
1 | using Hangfire.HttpJob.Agent.Config;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.Options;
4 |
5 | namespace Hangfire.HttpJob.Agent.PostgreSqlConsole.Config
6 | {
7 | public sealed class PostgreSqlConsoleOptionsConfigurer : ConfigureJobAgentConsoleOptions
8 | {
9 | public PostgreSqlConsoleOptionsConfigurer(IConfiguration configuration) : base(configuration)
10 | {
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.PostgreSqlConsole/PostgreSqlStorageOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.HttpJob.Agent.PostgreSqlConsole
4 | {
5 | public class PostgreSqlStorageOptions
6 | {
7 | // hangfire.PostgreSql不支持table prefix,此处留空
8 | public string TablePrefix { get; set; } = "";
9 | public string HangfireDbConnString { get; set; }
10 | public int ExpireAtDays { get; set; } = 7;
11 | public TimeSpan? ExpireAt { get; set; }
12 | }
13 | }
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.RedisConsole/Hangfire.HttpJob.Agent.RedisConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0;net461
5 | true
6 | true
7 | yuz
8 | yuzd
9 |
10 | https://github.com/yuzd/Hangfire.HttpJob
11 | agent job console to hangfire redis
12 | 1.4.8
13 | MIT
14 | 1.4.8.0
15 | 1.4.8.0
16 |
17 |
18 |
19 |
20 |
21 |
22 | TRACE;NETCORE
23 |
24 |
25 | TRACE;OWIN
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.RedisConsole/RedisConsole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.HttpJob.Agent.RedisConsole
4 | {
5 | internal class RedisConsole : HangfireConsole
6 | {
7 | public RedisConsole(IHangfireStorage storage)
8 | {
9 | Storage = storage ?? throw new ArgumentNullException(nameof(IHangfireStorage));
10 | }
11 |
12 | public override IHangfireStorage Storage { get; }
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.RedisConsole/RedisConsoleOptionsConfigurer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Hangfire.HttpJob.Agent.Config;
5 | using Microsoft.Extensions.Configuration;
6 | using Microsoft.Extensions.Options;
7 |
8 | namespace Hangfire.HttpJob.Agent.RedisConsole.Config
9 | {
10 | public sealed class RedisConsoleOptionsConfigurer : ConfigureJobAgentConsoleOptions
11 | {
12 | public RedisConsoleOptionsConfigurer(IConfiguration configuration) : base(configuration)
13 | {
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent.RedisConsole/RedisStorageOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Hangfire.HttpJob.Agent.RedisConsole
6 | {
7 | public class RedisStorageOptions
8 | {
9 | public string TablePrefix { get; set; } = "hangfire";
10 | public string HangfireDb { get; set; }
11 | public int DataBase { get; set; }
12 | public int ExpireAtDays { get; set; } = 7;
13 | public TimeSpan? ExpireAt { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Attribute/HangJobUntilStopAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Hangfire.HttpJob.Agent.Attribute
6 | {
7 | ///
8 | /// 支持OnStart 运行支持 Hode住
9 | ///
10 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
11 | public class HangJobUntilStopAttribute : JobAttribute
12 | {
13 | public bool On { get; set; } = true;
14 |
15 | public HangJobUntilStopAttribute()
16 | {
17 | }
18 | public HangJobUntilStopAttribute(string registerId)
19 | {
20 | this.RegisterId = registerId;
21 | }
22 | public HangJobUntilStopAttribute(bool on)
23 | {
24 | On = on;
25 | }
26 |
27 | public HangJobUntilStopAttribute(string registerId,bool on)
28 | {
29 | this.RegisterId = registerId;
30 | On = on;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Attribute/JobAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | namespace Hangfire.HttpJob.Agent.Attribute
6 | {
7 | ///
8 | /// 表达式
9 | ///
10 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
11 | public class JobAttribute: System.Attribute
12 | {
13 | internal bool? enableAutoRegister;
14 |
15 | ///
16 | /// 是否开启自动注册
17 | ///
18 | public bool EnableAutoRegister {
19 | get
20 | {
21 | if (enableAutoRegister == null) return false;
22 | return enableAutoRegister.Value;
23 | }
24 | set { enableAutoRegister = value; }
25 | }
26 |
27 | ///
28 | /// 注册的job名称 为空的话默认是 job的class 和namespace的 md5 16位的
29 | ///
30 | public string RegisterId { get; set; }
31 |
32 | ///
33 | /// 注册的job别名 默认别名为class的name
34 | ///
35 | public string RegisterName { get; set; }
36 |
37 | }
38 | }
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Attribute/SingletonJobAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Hangfire.HttpJob.Agent.Attribute
6 | {
7 | ///
8 | /// 单例的 如果没运行玩再次运行会忽略执行
9 | ///
10 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
11 | public class SingletonJobAttribute : JobAttribute
12 | {
13 | public SingletonJobAttribute()
14 | {
15 |
16 | }
17 | public SingletonJobAttribute(string registerId)
18 | {
19 | this.RegisterId = registerId;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Attribute/TransientJobAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Hangfire.HttpJob.Agent.Attribute
6 | {
7 | ///
8 | /// 支持并发运行
9 | ///
10 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
11 | public class TransientJobAttribute : JobAttribute
12 | {
13 | public TransientJobAttribute()
14 | {
15 |
16 | }
17 | public TransientJobAttribute(string registerId)
18 | {
19 | this.RegisterId = registerId;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Config/ConfigureJobAgentConsoleOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Microsoft.Extensions.Configuration;
5 | using Microsoft.Extensions.Options;
6 |
7 | namespace Hangfire.HttpJob.Agent.Config
8 | {
9 | public class ConfigureJobAgentConsoleOptions : IConfigureOptions where T:class
10 | {
11 | private readonly IConfiguration configuration;
12 |
13 | public ConfigureJobAgentConsoleOptions(IConfiguration configuration)
14 | {
15 | this.configuration = configuration;
16 | }
17 | public void Configure(T options)
18 | {
19 | configuration.GetSection("JobAgent:HangfireConsol").Bind(options);
20 | }
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Config/ConfigureJobAgentOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Microsoft.Extensions.Configuration;
5 | using Microsoft.Extensions.Options;
6 |
7 | namespace Hangfire.HttpJob.Agent.Config
8 | {
9 | public class ConfigureJobAgentOptions : IConfigureOptions
10 | {
11 | private readonly IConfiguration configuration;
12 |
13 | public ConfigureJobAgentOptions(IConfiguration configuration)
14 | {
15 | this.configuration = configuration;
16 | }
17 | public void Configure(JobAgentOptions options)
18 | {
19 | configuration.GetSection("JobAgent").Bind(options);
20 | }
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Config/JobAgentOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Hangfire.HttpJob.Agent.Config
6 | {
7 | ///
8 | /// JobAgent
9 | ///
10 | public class JobAgentOptions
11 | {
12 | ///
13 | /// 是否开启jobagent功能 总开关
14 | ///
15 | public bool Enabled { get; set; } = true;
16 |
17 | ///
18 | /// jobagent的路由
19 | ///
20 | public string SitemapUrl { get; set; } = "/jobagent";
21 |
22 | ///
23 | /// 是否开启basicAuth验证
24 | ///
25 | public bool EnabledBasicAuth { get; set; }
26 |
27 | ///
28 | /// basicauth验证用户名
29 | ///
30 | public string BasicUserName { get; set; }
31 |
32 | ///
33 | /// basicauth验证密码
34 | ///
35 | public string BasicUserPwd { get; set; }
36 |
37 | ///
38 | /// 是否开启自动注册的开关
39 | ///
40 | public bool EnableAutoRegister { get; set; }
41 |
42 | ///
43 | /// 注册job的地址 也就是hangfire调度server的地址
44 | ///
45 | public string RegisterHangfireUrl { get; set; }
46 | ///
47 | /// 当前启动agent的Host
48 | ///
49 | public string RegisterAgentHost { get; set; }
50 |
51 | ///
52 | /// basicauth验证用户名
53 | ///
54 | public string RegisterHangfireBasicName { get; set; }
55 |
56 | ///
57 | /// basicauth验证密码
58 | ///
59 | public string RegisterHangfireBasicPwd { get; set; }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Config/JobAgentOptionsConfigurer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Hangfire.HttpJob.Agent.Config
6 | {
7 | public sealed class JobAgentOptionsConfigurer
8 | {
9 | private readonly JobAgentOptions options;
10 |
11 | internal JobAgentOptionsConfigurer(JobAgentOptions options)
12 | {
13 | this.options = options;
14 | }
15 |
16 | public JobAgentOptionsConfigurer Enabled(bool enable = true)
17 | {
18 | options.Enabled = enable;
19 | return this;
20 | }
21 |
22 | public JobAgentOptionsConfigurer WithSitemap(string absoluteSitemapUri)
23 | {
24 | options.SitemapUrl = absoluteSitemapUri;
25 | return this;
26 | }
27 |
28 | public JobAgentOptionsConfigurer EnabledBasicAuth(bool enabledBasicAuth)
29 | {
30 | options.EnabledBasicAuth = enabledBasicAuth;
31 | return this;
32 | }
33 |
34 | public JobAgentOptionsConfigurer WithBasicUserName(string basicUserName)
35 | {
36 | options.BasicUserName = basicUserName;
37 | return this;
38 | }
39 |
40 | public JobAgentOptionsConfigurer WithBasicUserPwd(string basicUserPwd)
41 | {
42 | options.BasicUserPwd = basicUserPwd;
43 | return this;
44 | }
45 |
46 | public JobAgentOptionsConfigurer WithEnableAutoRegister(bool enableAutoRegister)
47 | {
48 | options.EnableAutoRegister = enableAutoRegister;
49 | return this;
50 | }
51 |
52 | public JobAgentOptionsConfigurer WithRegisterHangfireUrl(string registerUrl)
53 | {
54 | options.RegisterHangfireUrl = registerUrl;
55 | return this;
56 | }
57 | public JobAgentOptionsConfigurer WithRegisterAgentHost(string registerAgentHost)
58 | {
59 | options.RegisterAgentHost = registerAgentHost;
60 | return this;
61 | }
62 |
63 | public JobAgentOptionsConfigurer WithRegisterHangfireBasicName(string registerBasicUserName)
64 | {
65 | options.RegisterHangfireBasicName = registerBasicUserName;
66 | return this;
67 | }
68 |
69 | public JobAgentOptionsConfigurer WithRegisterHangfireBasicPwdd(string registerBasicUserPwd)
70 | {
71 | options.RegisterHangfireBasicPwd = registerBasicUserPwd;
72 | return this;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Config/JobAgentServiceConfigurer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Hangfire.HttpJob.Agent.Attribute;
6 | using Microsoft.Extensions.DependencyInjection;
7 |
8 | namespace Hangfire.HttpJob.Agent.Config
9 | {
10 |
11 |
12 | public class JobAgentServiceConfigurer
13 | {
14 |
15 | internal static readonly ConcurrentDictionary JobAgentDic = new ConcurrentDictionary();
16 |
17 | public IServiceCollection Services { get; }
18 |
19 | public JobAgentServiceConfigurer(IServiceCollection serviceCollection)
20 | {
21 | Services = serviceCollection;
22 | }
23 |
24 | ///
25 | /// 添加一次 只能运行一次 运行结束才能运行下一次
26 | ///
27 | ///
28 | ///
29 | public JobAgentServiceConfigurer AddJobAgent() where T : JobAgent
30 | {
31 | var type = typeof(T);
32 | AddJobAgent(type);
33 | return this;
34 | }
35 |
36 | public JobAgentServiceConfigurer AddJobAgent(Type type)
37 | {
38 | if (!typeof(JobAgent).IsAssignableFrom(type))
39 | {
40 | throw new InvalidCastException($"type:{type.Name} is not AssignableFrom typeOf JobAgent");
41 | }
42 |
43 | if (JobAgentDic.ContainsKey(type))
44 | {
45 | throw new InvalidOperationException($"type:{type.Name} is registerd!");
46 | }
47 |
48 | //这三种标签不可以共存
49 | var scopedJobAttribute = type.GetCustomAttribute();
50 | var singletonJobAttribute = type.GetCustomAttribute();//没有它就是默认的
51 | var hangJobUntilStopAttribute = type.GetCustomAttribute();
52 | if(scopedJobAttribute==null && hangJobUntilStopAttribute == null && singletonJobAttribute == null) singletonJobAttribute = new SingletonJobAttribute();
53 | var array = new object[] {scopedJobAttribute, singletonJobAttribute, hangJobUntilStopAttribute};
54 |
55 | if (array.Count(r => r != null) > 1)
56 | {
57 | throw new InvalidCastException($"type:{type.Name} can not init with mulit xxxxJobAttribute!");
58 | }
59 |
60 | if (!(array.FirstOrDefault(r=>r!=null) is JobAttribute regesterMeta))
61 | {
62 | throw new InvalidCastException($"type:{type.Name} is not AssignableFrom typeOf JobAttribute");
63 | }
64 |
65 | var meta = new JobMetaData
66 | {
67 | RegisterId = regesterMeta.RegisterId,
68 | RegisterName = regesterMeta.RegisterName,
69 | EnableAutoRegister = regesterMeta.enableAutoRegister
70 | };
71 |
72 | if (hangJobUntilStopAttribute != null)
73 | {
74 | meta.Hang = hangJobUntilStopAttribute.On;
75 | }
76 |
77 | if (scopedJobAttribute != null)
78 | {
79 | meta.Transien = true;
80 | if (JobAgentDic.TryAdd(type, meta))
81 | {
82 | Services.AddTransient(type);
83 | }
84 | return this;
85 | }
86 |
87 | meta.Transien = false;
88 | if (JobAgentDic.TryAdd(type, meta))
89 | {
90 | Services.AddSingleton(type);
91 | }
92 | return this;
93 | }
94 |
95 | public JobAgentServiceConfigurer AddJobAgent(Assembly assembly)
96 | {
97 | var types = assembly.GetExportedTypes();
98 | var agengList = (from t in types
99 | where typeof(JobAgent).IsAssignableFrom(t) &&
100 | !t.IsAbstract &&
101 | !t.IsInterface
102 | select t).ToList();
103 | agengList.ForEach(r=>AddJobAgent(r));
104 | return this;
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Config/JobMetaData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Hangfire.HttpJob.Agent.Config
6 | {
7 | internal class JobMetaData
8 | {
9 | public bool Transien { get; set; }
10 | public bool Hang { get; set; }
11 |
12 | public string RegisterName { get; set; }
13 | public string RegisterId { get; set; }
14 | public bool? EnableAutoRegister { get; set; }
15 | public bool AutoRegisterResult { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Console/ConsoleFontColor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Threading;
6 | using Newtonsoft.Json;
7 |
8 | namespace Hangfire.HttpJob.Agent
9 | {
10 | public class ConsoleFontColor
11 | {
12 | /// The color black.
13 | public static readonly ConsoleFontColor Black = new ConsoleFontColor("#000000");
14 | /// The color dark blue.
15 | public static readonly ConsoleFontColor DarkBlue = new ConsoleFontColor("#000080");
16 | /// The color dark green.
17 | public static readonly ConsoleFontColor DarkGreen = new ConsoleFontColor("#008000");
18 | /// The color dark cyan (dark blue-green).
19 | public static readonly ConsoleFontColor DarkCyan = new ConsoleFontColor("#008080");
20 | /// The color dark red.
21 | public static readonly ConsoleFontColor DarkRed = new ConsoleFontColor("#800000");
22 | /// The color dark magenta (dark purplish-red).
23 | public static readonly ConsoleFontColor DarkMagenta = new ConsoleFontColor("#800080");
24 | /// The color dark yellow (ochre).
25 | public static readonly ConsoleFontColor DarkYellow = new ConsoleFontColor("#808000");
26 | /// The color gray.
27 | public static readonly ConsoleFontColor Gray = new ConsoleFontColor("#c0c0c0");
28 | /// The color dark gray.
29 | public static readonly ConsoleFontColor DarkGray = new ConsoleFontColor("#808080");
30 | /// The color blue.
31 | public static readonly ConsoleFontColor Blue = new ConsoleFontColor("#0000ff");
32 | /// The color green.
33 | public static readonly ConsoleFontColor Green = new ConsoleFontColor("#00ff00");
34 | /// The color cyan (blue-green).
35 | public static readonly ConsoleFontColor Cyan = new ConsoleFontColor("#00ffff");
36 | /// The color red.
37 | public static readonly ConsoleFontColor Red = new ConsoleFontColor("#ff0000");
38 | /// The color magenta (purplish-red).
39 | public static readonly ConsoleFontColor Magenta = new ConsoleFontColor("#ff00ff");
40 | /// The color yellow.
41 | public static readonly ConsoleFontColor Yellow = new ConsoleFontColor("#ffff00");
42 | /// The color white.
43 | public static readonly ConsoleFontColor White = new ConsoleFontColor("#ffffff");
44 | private readonly string _color;
45 |
46 | private ConsoleFontColor(string color)
47 | {
48 | this._color = color;
49 | }
50 |
51 | ///
52 | public override string ToString()
53 | {
54 | return this._color;
55 | }
56 |
57 | ///
58 | /// Implicitly converts to .
59 | ///
60 | public static implicit operator string(ConsoleFontColor color)
61 | {
62 | return color?._color;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Console/ConsoleInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Threading;
6 | using Newtonsoft.Json;
7 |
8 | namespace Hangfire.HttpJob.Agent
9 | {
10 | public class ConsoleInfo
11 | {
12 | public string SetKey { get; set; }
13 | public int ProgressBarId { get; set; }
14 | public string HashKey { get; set; }
15 | public DateTime StartTime { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Console/ConsoleLine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Threading;
6 | using Newtonsoft.Json;
7 |
8 | namespace Hangfire.HttpJob.Agent
9 | {
10 | internal class ConsoleLine
11 | {
12 | ///
13 | /// Time offset since console timestamp in fractional seconds
14 | ///
15 | [JsonProperty("t", Required = Required.Always)]
16 | public double TimeOffset { get; set; }
17 |
18 | ///
19 | /// True if is a Hash reference.
20 | ///
21 | [JsonProperty("r", DefaultValueHandling = DefaultValueHandling.Ignore)]
22 | public bool IsReference { get; set; }
23 |
24 | ///
25 | /// Message text, or message reference, or progress bar id
26 | ///
27 | [JsonProperty("s", Required = Required.Always)]
28 | public string Message { get; set; }
29 |
30 | ///
31 | /// Text color for this message
32 | ///
33 | [JsonProperty("c", DefaultValueHandling = DefaultValueHandling.Ignore)]
34 | public string TextColor { get; set; }
35 |
36 | ///
37 | /// Value update for a progress bar
38 | ///
39 | [JsonProperty("p", DefaultValueHandling = DefaultValueHandling.Ignore)]
40 | public double? ProgressValue { get; set; }
41 |
42 | ///
43 | /// Optional name for a progress bar
44 | ///
45 | [JsonProperty("n", DefaultValueHandling = DefaultValueHandling.Ignore)]
46 | public string ProgressName { get; set; }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Console/HangfireProgressBar.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Threading;
6 | using Newtonsoft.Json;
7 |
8 | namespace Hangfire.HttpJob.Agent
9 | {
10 |
11 | public class HangfireProgressBar : IProgressBar
12 | {
13 | private readonly HangfireConsole _context;
14 | private readonly string _progressBarId;
15 | private string _name;
16 | private string _color;
17 | private double _value;
18 |
19 | internal HangfireProgressBar(HangfireConsole context, string progressBarId, string name, ConsoleFontColor color = null)
20 | {
21 | if (string.IsNullOrEmpty(progressBarId))
22 | throw new ArgumentNullException(nameof(progressBarId));
23 |
24 | _context = context ?? throw new ArgumentNullException(nameof(context));
25 | _progressBarId = progressBarId;
26 | _name = name;
27 | _color = color;
28 | _value = -1;
29 | }
30 |
31 |
32 |
33 | public void SetValue(int value)
34 | {
35 | SetValue((double)value);
36 | }
37 |
38 | public void SetValue(double value)
39 | {
40 | value = Math.Round(value, 1);
41 |
42 | if (value < 0 || value > 100)
43 | throw new ArgumentOutOfRangeException(nameof(value), "Value should be in range 0..100");
44 |
45 | // ReSharper disable once CompareOfFloatsByEqualityOperator
46 | if (Interlocked.Exchange(ref _value, value) == value) return;
47 |
48 | _context.WriteBar(new ConsoleLine() { Message = _progressBarId, ProgressName = _name, ProgressValue = value, TextColor = _color });
49 |
50 | _name = String.IsNullOrEmpty(_name) ? null : _name;
51 | _color = String.IsNullOrEmpty(_color) ? null : _color;
52 | }
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Console/IHangfireConsole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Threading;
6 | using Newtonsoft.Json;
7 |
8 | namespace Hangfire.HttpJob.Agent
9 | {
10 |
11 | public interface IHangfireStorage:IDisposable
12 | {
13 | void SetRangeInHash(string key, IEnumerable> keyValuePairs);
14 |
15 | void AddToSet(string key, string value, double score);
16 | }
17 |
18 | public interface ICommonConsole
19 | {
20 | void Error(string err);
21 | void Error(Exception err);
22 | void Info(string info);
23 | void Warning(string warn);
24 |
25 | void Warning(Exception warn);
26 | }
27 |
28 | public interface IHangfireConsole: ICommonConsole
29 | {
30 | void WriteLine(string message, ConsoleFontColor fontColor = null);
31 | IProgressBar WriteProgressBar(string name, double initValue=1, ConsoleFontColor color = null);
32 | }
33 |
34 |
35 | ///
36 | /// Progress bar line inside console.
37 | ///
38 | public interface IProgressBar
39 | {
40 | ///
41 | /// Updates a value of a progress bar.
42 | ///
43 | /// New value
44 | void SetValue(int value);
45 |
46 | ///
47 | /// Updates a value of a progress bar.
48 | ///
49 | /// New value
50 | void SetValue(double value);
51 | }
52 |
53 | public interface IHangfireConsoleInit
54 | {
55 | void Init(ConsoleInfo consoleInfo);
56 | }
57 |
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Console/IStorageFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Text;
5 | using System.Threading;
6 | using Newtonsoft.Json;
7 |
8 | namespace Hangfire.HttpJob.Agent
9 | {
10 | public interface IStorageFactory
11 | {
12 | IHangfireStorage CreateHangfireStorage(JobStorageConfig config);
13 | IHangfireConsole CreateHangforeConsole(IHangfireStorage storage);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Hangfire.HttpJob.Agent.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0;net461
5 | yuzd
6 | Hangfire HttpJob Agent
7 | HttpJob Agent for Hangfire
8 | https://github.com/yuzd/Hangfire.HttpJob
9 | true
10 | yuzd
11 | 1.5.1
12 | true
13 | MIT
14 | 1.5.1.0
15 | 1.5.1.0
16 |
17 |
18 |
19 |
20 |
21 | TRACE;NETCORE
22 |
23 |
24 | TRACE;OWIN
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/JobAgentApplicationBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading;
5 | using Hangfire.HttpJob.Agent.Config;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Hosting;
11 | using Microsoft.Extensions.Logging;
12 | using Microsoft.Extensions.Options;
13 |
14 | #if !NETCORE
15 | using Owin;
16 |
17 | #endif
18 |
19 | namespace Hangfire.HttpJob.Agent
20 | {
21 | public static class JobAgentApplicationBuilderExtensions
22 | {
23 | #if NETCORE
24 | public static IApplicationBuilder UseHangfireHttpJobAgent(this IApplicationBuilder app,
25 | Action configureOptions = null)
26 | #else
27 | public static IAppBuilder UseHangfireHttpJobAgent(this IAppBuilder app,IServiceCollection services,
28 | Action configureOptions = null)
29 | #endif
30 |
31 | {
32 |
33 | #if NETCORE
34 | var sp = app.ApplicationServices;
35 | #else
36 | var sp = services.BuildServiceProvider();//OWIN
37 | var configRoot = sp.GetRequiredService();
38 | services.Configure(configRoot.GetSection("JobAgent"));
39 | sp = services.BuildServiceProvider();//OWIN
40 | #endif
41 | var evt = new EventId(1, "Hangfire.HttpJob.Agent");
42 | var loggerFactory = sp.GetService();
43 | var logger = loggerFactory.CreateLogger();
44 | var options = sp.GetService>();
45 |
46 | var configurer = new JobAgentOptionsConfigurer(options.Value);
47 | try
48 | {
49 | configureOptions?.Invoke(configurer);
50 | }
51 | catch (Exception exception)
52 | {
53 | logger.LogCritical(evt, exception, "Failed to configure JobAgent middleware");
54 | }
55 |
56 | if (!options.Value.Enabled)
57 | {
58 | return app;
59 | }
60 |
61 |
62 | if (string.IsNullOrEmpty(options.Value.SitemapUrl)) options.Value.SitemapUrl = "/jobagent";
63 | foreach (KeyValuePair jobAgent in JobAgentServiceConfigurer.JobAgentDic)
64 | {
65 | logger.LogInformation(evt, $"【HttpJobAgent】 - [{jobAgent.Key.Name}] [Transient:{jobAgent.Value.Transien}] [HangJob:{jobAgent.Value.Hang}] - Registered");
66 | }
67 | var registerService = new JobAgentRegisterService(options, loggerFactory);
68 |
69 | #if NETCORE
70 | var lifeRegister = sp.GetRequiredService();
71 | lifeRegister.ApplicationStarted.Register(async () =>
72 | {
73 | await registerService.StartAsync(CancellationToken.None);
74 | });
75 | lifeRegister.ApplicationStopping.Register(async () =>
76 | {
77 | await registerService.StopAsync(CancellationToken.None);
78 | });
79 | #endif
80 | logger.LogInformation(evt, "【HttpJobAgent】 - Registered HttpJobAgent middleware to respond to {path}", new { path = options.Value.SitemapUrl });
81 | #if NETCORE
82 | app.Map(options.Value.SitemapUrl, robotsApp =>
83 | {
84 | robotsApp.UseMiddleware();
85 | });
86 | #else
87 | app.Map(options.Value.SitemapUrl, robotsApp =>
88 | {
89 | robotsApp.Use(logger, options, loggerFactory, sp);
90 | });
91 |
92 | registerService.StartAsync(CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult();
93 | #endif
94 |
95 | return app;
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/JobAgentServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using System.Text;
5 | using Hangfire.HttpJob.Agent.Config;
6 | using Microsoft.Extensions.DependencyInjection;
7 | using Microsoft.Extensions.DependencyInjection.Extensions;
8 | using Microsoft.Extensions.Options;
9 |
10 | namespace Hangfire.HttpJob.Agent
11 | {
12 | public static class JobAgentServiceCollectionExtensions
13 | {
14 | public static IServiceCollection AddHangfireHttpJobAgent(this IServiceCollection serviceCollection, Action configure = null)
15 | {
16 | serviceCollection.AddOptions();
17 | serviceCollection.TryAddSingleton, ConfigureJobAgentOptions>();
18 | var configurer = new JobAgentServiceConfigurer(serviceCollection);
19 | if (configure == null)
20 | {
21 | var assembly = Assembly.GetEntryAssembly();
22 | configure = (c) => { c.AddJobAgent(assembly); };
23 | }
24 | configure.Invoke(configurer);
25 | serviceCollection.TryAddSingleton();
26 | return serviceCollection;
27 |
28 | }
29 |
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/JobStatus.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Hangfire.HttpJob.Agent
8 | {
9 | internal enum JobStatus
10 | {
11 | Default,
12 | Running,
13 | Stopping,
14 | Stoped,
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Util/CodingUtil.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Newtonsoft.Json;
3 |
4 | namespace Hangfire.HttpJob.Agent.Util
5 | {
6 | internal static class CodingUtil
7 | {
8 |
9 |
10 | public static T ToJson(this string str)
11 | {
12 | try
13 | {
14 | return JsonConvert.DeserializeObject(str);
15 | }
16 | catch (Exception )
17 | {
18 | return default(T);
19 | }
20 |
21 | }
22 |
23 | ///
24 | ///由秒数得到日期几天几小时。。。
25 | ///秒数
27 | ///0:转换后带秒,1:转换后不带秒
28 | ///几天几小时几分几秒
29 | public static string ParseTimeSeconds(int t, int type = 0)
30 | {
31 | string r = "";
32 | int day, hour, minute, second;
33 | if (t >= 86400) //天,
34 | {
35 | day = Convert.ToInt16(t / 86400);
36 | hour = Convert.ToInt16((t % 86400) / 3600);
37 | minute = Convert.ToInt16((t % 86400 % 3600) / 60);
38 | second = Convert.ToInt16(t % 86400 % 3600 % 60);
39 | if (type == 0)
40 | r = day + ("D") + hour + ("H") + minute + ("M") + second + ("S");
41 | else
42 | r = day + ("D") + hour + ("H") + minute + ("M");
43 |
44 | }
45 | else if (t >= 3600)//时,
46 | {
47 | hour = Convert.ToInt16(t / 3600);
48 | minute = Convert.ToInt16((t % 3600) / 60);
49 | second = Convert.ToInt16(t % 3600 % 60);
50 | if (type == 0)
51 | r = hour + ("H") + minute + ("M") + second + ("S");
52 | else
53 | r = hour + ("H") + minute + ("M");
54 | }
55 | else if (t >= 60)//分
56 | {
57 | minute = Convert.ToInt16(t / 60);
58 | second = Convert.ToInt16(t % 60);
59 | r = minute + ("M") + second + ("S");
60 | }
61 | else
62 | {
63 | second = Convert.ToInt16(t);
64 | r = second + ("S");
65 | }
66 | return r;
67 | }
68 |
69 | }
70 | }
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Util/LazyConcurrentDictionary.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Threading;
5 |
6 | namespace Hangfire.HttpJob.Agent.Util
7 | {
8 | internal class LazyConcurrentDictionary
9 | {
10 | private readonly ConcurrentDictionary>> concurrentDictionary;
11 |
12 |
13 | public LazyConcurrentDictionary()
14 | {
15 | this.concurrentDictionary = new ConcurrentDictionary>>();
16 | }
17 |
18 | public ConcurrentDictionary GetOrAdd(string key, Func> valueFactory)
19 | {
20 | var lazyResult =
21 | this.concurrentDictionary.GetOrAdd(key, k => new Lazy>(() => valueFactory(k), LazyThreadSafetyMode.ExecutionAndPublication));
22 |
23 | return lazyResult.Value;
24 | }
25 |
26 | public bool TryGetValue(string key, out ConcurrentDictionary value)
27 | {
28 | var rt = concurrentDictionary.TryGetValue(key, out Lazy> valueLazy);
29 | value = rt ? valueLazy.Value : new ConcurrentDictionary();
30 | return rt;
31 | }
32 |
33 | public bool TryRemove(string key, out ConcurrentDictionary value)
34 | {
35 | var rt = concurrentDictionary.TryRemove(key, out Lazy> valueLazy);
36 | value = rt ? valueLazy.Value : new ConcurrentDictionary();
37 | return rt;
38 | }
39 |
40 | public void JobRemove(object state,TransitentJobDisposeArgs args)
41 | {
42 | try
43 | {
44 | if(args == null) return;
45 | if (string.IsNullOrEmpty(args.Key) || string.IsNullOrEmpty(args.Guid)) return;
46 | if(this.TryGetValue(args.Key ,out var dic))
47 | {
48 | dic.TryRemove(args.Guid,out _);
49 | }
50 | }
51 | catch (Exception)
52 | {
53 | //ignore
54 | }
55 | }
56 | }
57 |
58 | internal class TransitentJobDisposeArgs : EventArgs
59 | {
60 | public string Key { get; private set; }
61 | public string Guid { get; private set; }
62 |
63 | public TransitentJobDisposeArgs(string key,string guid)
64 | {
65 | Key = key;
66 | Guid = guid;
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/Agent/Hangfire.HttpJob.Agent/Util/LoggerConsole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace Hangfire.HttpJob.Agent.Util
7 | {
8 | internal class LoggerConsole : HangfireConsole
9 | {
10 | private readonly ILogger _logger;
11 | public LoggerConsole(ILogger logger)
12 | {
13 | _logger = logger;
14 | }
15 |
16 | public override IHangfireStorage Storage => new LocalLoggerConsole(_logger);
17 | }
18 |
19 | internal class LocalLoggerConsole : IHangfireStorage
20 | {
21 | private readonly ILogger _logger;
22 |
23 | public LocalLoggerConsole(ILogger logger)
24 | {
25 | _logger = logger;
26 | }
27 | public void Dispose()
28 | {
29 | }
30 |
31 | public void SetRangeInHash(string key, IEnumerable> keyValuePairs)
32 | {
33 | foreach (var keyvalue in keyValuePairs)
34 | {
35 | _logger.LogInformation(new EventId(0, key), keyvalue.Key + "->" + keyvalue.Value);
36 | }
37 |
38 | }
39 |
40 | public void AddToSet(string key, string value, double score)
41 | {
42 | _logger.LogInformation(key + "->" + value);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Agent/Template/README.md:
--------------------------------------------------------------------------------
1 | ## HttpAgent Project Template
2 |
3 | ### Push to Nuget
4 |
5 | * dotnet pack
6 | * modified Template.csproj
7 | * push to nuget.org
8 |
9 |
10 | ### Quick Start
11 |
12 | **install**
13 | ```
14 | dotnet new -i HttpJob.Agent.Template
15 | ```
16 |
17 | **usage**
18 | ```
19 | ## --type default value is RedisConsole
20 | dotnet new agent -n=Hello --type=MysqlConsole
21 | ```
--------------------------------------------------------------------------------
/Agent/Template/Template.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Template
4 | 1.0.1
5 | HttpJob.Agent.Template
6 | HttpJob Agent Quick Start Project Template
7 | agent
8 | dotnet-new;templates;httpjob;hangfire
9 | netstandard2.0
10 |
11 | true
12 | false
13 | content
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/.template.config/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/template",
3 | "author": "agent",
4 | "classifications": [ "agent", "webapi","httpjob" ],
5 | "identity": "HttpJob.Agent.Template",
6 | "name": "Hangfire HttpJob Agent QuickStart Project Template",
7 | "shortName": "agent",
8 | "sourceName": "Template",
9 | "preferNameDirectory": true,
10 | "symbols":{
11 | "type": {
12 | "type": "parameter",
13 | "defaultValue": "RedisConsole",
14 | "replaces":"AgentType"
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/Jobs/TestHangJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace Template.Jobs
10 | {
11 | [HangJobUntilStop(RegisterName = "HangJob测试")]
12 | public class TestHangJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestHangJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestHangJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info(nameof(OnStart) + (jobContext.Param ?? string.Empty));
24 |
25 | while (!jobContext.CancelToken.IsCancellationRequested)
26 | {
27 | jobContext.Console.Info("dddd");
28 | await Task.Delay(1000 * 10);
29 | }
30 | throw new Exception("dddddd");
31 | jobContext.Console.Warning("game over");
32 | }
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/Jobs/TestJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace Template.Jobs
10 | {
11 | [SingletonJob(RegisterName = "单例job")]//不打这个标签也行 默认就是单例的
12 | public class TestJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info("info消息");
24 | jobContext.Console.Warning("waring消息");
25 | jobContext.Console.Error("error消息");
26 | jobContext.Console.Info("开始等待1秒");
27 | await Task.Delay(1000 * 1);
28 | jobContext.Console.Info("结束等待1秒");
29 | jobContext.Console.WriteLine("开始测试Progressbar", ConsoleFontColor.Cyan);
30 |
31 | var bar = jobContext.Console.WriteProgressBar("testbar");
32 | for (int i = 0; i < 10; i++)
33 | {
34 | bar.SetValue(i * 10);
35 | await Task.Delay(1000);
36 | }
37 | }
38 |
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/Jobs/TestTransientJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Hangfire.HttpJob.Agent;
7 | using Hangfire.HttpJob.Agent.Attribute;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace Template.Jobs
11 | {
12 | [TransientJob(RegisterName = "多例job")]
13 | public class TestTransientJob:JobAgent
14 | {
15 | private readonly ILogger _logger;
16 |
17 | public TestTransientJob(ILogger logger)
18 | {
19 | _logger = logger;
20 | _logger.LogInformation($"Create {nameof(TestTransientJob)} Instance Success");
21 | }
22 | public override async Task OnStart(JobContext jobContext)
23 | {
24 | jobContext.Console.Warning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
25 | _logger.LogWarning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
26 | await Task.Delay(5000);
27 | _logger.LogWarning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
28 | jobContext.Console.Warning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
29 | }
30 |
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/NLog.Config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Hosting;
10 | using Microsoft.Extensions.Logging;
11 | using NLog.Web;
12 |
13 | namespace TestSqlserverHangfireAgent
14 | {
15 | public class Program
16 | {
17 | public static void Main(string[] args)
18 | {
19 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.Config").GetCurrentClassLogger();
20 | try
21 | {
22 | logger.Debug("init main");
23 | CreateHostBuilder(args).Build().Run();
24 | }
25 | catch (Exception ex)
26 | {
27 | //NLog: catch setup errors
28 | logger.Error(ex, "Stopped program because of exception");
29 | throw;
30 | }
31 | finally
32 | {
33 | // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
34 | NLog.LogManager.Shutdown();
35 | }
36 | }
37 |
38 | public static IHostBuilder CreateHostBuilder(string[] args) =>
39 | Host.CreateDefaultBuilder(args)
40 | .ConfigureWebHostDefaults(webBuilder =>
41 | {
42 | webBuilder.UseStartup()
43 | .ConfigureLogging(logging =>
44 | {
45 | logging.ClearProviders();
46 | #if DEBUG
47 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
48 |
49 | #else
50 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
51 | #endif
52 | }).UseNLog();
53 | });
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "TestHangfireRedisAgent": {
4 | "commandName": "Project",
5 | "launchBrowser": true,
6 | "applicationUrl": "http://0.0.0.0:5000",
7 | "environmentVariables": {
8 | "ASPNETCORE_ENVIRONMENT": "Development"
9 | }
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.RedisConsole;
7 | using Microsoft.AspNetCore.Builder;
8 | using Microsoft.AspNetCore.Hosting;
9 | using Microsoft.AspNetCore.Http;
10 | using Microsoft.Extensions.DependencyInjection;
11 | using Microsoft.Extensions.Logging;
12 | using NLog.Extensions.Logging;
13 |
14 | namespace TestSqlserverHangfireAgent
15 | {
16 | public class Startup
17 | {
18 | // This method gets called by the runtime. Use this method to add services to the container.
19 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
20 | public void ConfigureServices(IServiceCollection services)
21 | {
22 | services.AddHangfireJobAgent();
23 | }
24 |
25 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
26 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory logging)
27 | {
28 | app.UseHangfireJobAgent();
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/Template.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Always
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Agent/Template/templates/Template/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "JobAgent": {
11 | "Enabled": true,
12 | "SitemapUrl": "/jobagent",
13 | "EnabledBasicAuth": true,
14 | "BasicUserName": "test",
15 | "BasicUserPwd": "123456",
16 | "EnableAutoRegister": true,
17 | "RegisterAgentHost": "http://localhost:5002",
18 | "RegisterHangfireUrl": "http://localhost:5000/job",
19 | "RegisterHangfireBasicName": "admin",
20 | "RegisterHangfireBasicPwd": "test"
21 | }
22 | }
--------------------------------------------------------------------------------
/Client/Hangfire.HttpJob.Client/Hangfire.HttpJob.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net45;netstandard2.0
5 | true
6 | yuzd
7 | Hangfire HttpJob Client
8 | zdyu
9 | https://github.com/yuzd/Hangfire.HttpJob
10 | yuzd
11 | 1.2.9
12 | true
13 | MIT
14 | 1.2.9.0
15 | 1.2.9.0
16 |
17 |
18 |
19 | portable
20 | TRACE;DEBUG
21 |
22 |
23 |
24 | RELEASE
25 |
26 |
27 |
28 | $(DefineConstants);NETCORE
29 |
30 |
31 |
32 | TRACE;DEBUG;NET45
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Client/Hangfire.HttpJob.Client/HangfireHttpClientFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Net.Http;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using HttpClientFactory.Impl;
9 |
10 | namespace Hangfire.HttpJob.Client
11 | {
12 | internal class HangfireHttpClientFactory:PerHostHttpClientFactory
13 | {
14 | protected override HttpClient CreateHttpClient(HttpMessageHandler handler)
15 | {
16 | var client = new HttpClient(handler);
17 | client.DefaultRequestHeaders.ConnectionClose = false;
18 | client.Timeout = TimeSpan.FromHours(1);
19 | client.DefaultRequestHeaders.Add("UserAgent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36");
20 | return client;
21 | }
22 |
23 | protected override HttpMessageHandler CreateMessageHandler(string proxyUrl = null)
24 | {
25 | var handler = new HttpClientHandler();
26 | if (string.IsNullOrEmpty(proxyUrl))
27 | {
28 | handler.UseProxy = false;
29 | }
30 | else
31 | {
32 | handler.UseProxy = true;
33 | handler.Proxy = new WebProxy(proxyUrl);
34 | }
35 |
36 | handler.AllowAutoRedirect = false;
37 | handler.AutomaticDecompression = DecompressionMethods.None;
38 | handler.UseCookies = false;
39 | return handler;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Client/Hangfire.HttpJob.Client/HangfireJobResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Hangfire.HttpJob.Client
8 | {
9 | public class HangfirJobResult
10 | {
11 | public string ErrMessage { get; set; }
12 | public bool IsSuccess { get; set; }
13 |
14 | }
15 |
16 | public class AddBackgroundHangfirJobResult: HangfirJobResult
17 | {
18 | public string JobId { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Client/Hangfire.HttpJob.Client/HangfireServerPostOption.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Net.Http;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace Hangfire.HttpJob.Client
10 | {
11 |
12 | ///
13 | /// 其他额外设置
14 | ///
15 | public class HangfireServerPostOption
16 | {
17 | public HangfireServerPostOption()
18 | {
19 | TimeOut = 5000;
20 | ThrowException = false;
21 | }
22 |
23 | ///
24 | /// 请求HangfireServer的超时时间 毫秒
25 | ///
26 | public int TimeOut { get; set; }
27 |
28 | ///
29 | /// 请求HangfireServer的时候错误是否抛出
30 | ///
31 | public bool ThrowException { get; set; }
32 |
33 | ///
34 | /// 请求HangfireServer的basic 验证的用户名
35 | ///
36 | public string BasicUserName { get; set; }
37 |
38 | ///
39 | /// 请求HangfireServer的basic 验证的密码
40 | ///
41 | public string BasicPassword { get; set; }
42 |
43 | ///
44 | /// 代理
45 | ///
46 | public string ProxyUrl { get; set; }
47 |
48 | internal HttpClient HttpClient { get; set; }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Client/Hangfire.HttpJob.Client/RecurringJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Hangfire.HttpJob.Client
8 | {
9 |
10 | ///
11 | /// 循环job
12 | ///
13 | public class RecurringJob
14 | {
15 | public RecurringJob()
16 | {
17 | Method = "Post";
18 | ContentType = "application/json";
19 | Timeout = 20000;
20 | }
21 | ///
22 | /// 请求Url
23 | ///
24 | public string Url { get; set; }
25 |
26 | ///
27 | /// 请求参数
28 | ///
29 | public string Method { get; set; }
30 |
31 | ///
32 | /// 参数
33 | ///
34 | public object Data { get; set; }
35 |
36 | ///
37 | /// 类型
38 | ///
39 | public string ContentType { get; set; }
40 |
41 | ///
42 | /// 超时 毫秒
43 | ///
44 | public int Timeout { get; set; }
45 |
46 | ///
47 | /// Cron表达式
48 | ///
49 | public string Cron { get; set; }
50 |
51 | ///
52 | /// JOB的名称
53 | ///
54 | public string JobName { get; set; }
55 |
56 | ///
57 | /// job的唯一标识 如果没有设置值的话就等同于JobName
58 | ///
59 | public string RecurringJobIdentifier { get; set; }
60 |
61 | ///
62 | /// QueueName的名称 如果不配置就用默认的 DEFAULT
63 | ///
64 | public string QueueName { get; set; }
65 |
66 | ///
67 | /// 是否成功发送通知
68 | ///
69 | public bool SendSuccess { get; set; }
70 |
71 | ///
72 | /// 是否失败发送通知
73 | ///
74 | public bool SendFail { get; set; }
75 |
76 | ///
77 | /// 指定发送邮件
78 | ///
79 | public List Mail { get; set; }
80 |
81 | ///
82 | /// 开启失败重启
83 | ///
84 | public bool EnableRetry { get; set; }
85 |
86 | ///
87 | /// 错误尝试次数自定义
88 | ///
89 | public int RetryTimes { get; set; }
90 |
91 | ///
92 | /// 失败重试区间 半角逗号隔开
93 | ///
94 | public string RetryDelaysInSeconds { get; set; }
95 |
96 | ///
97 | /// basic 验证用户名
98 | ///
99 | public string BasicUserName { get; set; }
100 |
101 | ///
102 | /// basic 验证密码
103 | ///
104 | public string BasicPassword { get; set; }
105 |
106 | ///
107 | /// 代理设置
108 | ///
109 | public string AgentClass { get; set; }
110 |
111 | ///
112 | /// 判断是否成功还是失败的EL表达式
113 | ///
114 | public string CallbackEL { get; set; }
115 |
116 | ///
117 | /// Header
118 | ///
119 | public Dictionary Headers { get; set; } = new Dictionary();
120 |
121 | public HttpCallbackJob Success { get; set; }
122 | public HttpCallbackJob Fail { get; set; }
123 | ///
124 | /// 每个job运行的时区
125 | ///
126 | public string TimeZone { get; set; }
127 |
128 | ///
129 | /// 钉钉配置
130 | ///
131 | public DingTalkOption DingTalk { get; set; }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Dashboard/DynamicCssDispatcher.cs:
--------------------------------------------------------------------------------
1 | using Hangfire.Dashboard;
2 | using System;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 |
6 | namespace Hangfire.HttpJob.Dashboard
7 | {
8 | public class DynamicCssDispatcher : IDashboardDispatcher
9 | {
10 | private readonly HangfireHttpJobOptions _options;
11 | public DynamicCssDispatcher(HangfireHttpJobOptions options)
12 | {
13 | if (options == null)
14 | throw new ArgumentNullException(nameof(options));
15 |
16 | _options = options;
17 | }
18 |
19 | public Task Dispatch(DashboardContext context)
20 | {
21 | var builder = new StringBuilder();
22 |
23 | builder.AppendLine(".table tbody .tooltip{word-break: break-all;}");
24 |
25 | builder.AppendLine(".console, .console .line-buffer {")
26 | .Append(" color: ").Append("red").AppendLine(";")
27 | .AppendLine("}");
28 |
29 | if (context.Request != null)
30 | {
31 | if (context is AspNetCoreDashboardContext abc)
32 | {
33 | if (abc.HttpContext.Request.Headers.TryGetValue("Referer", out var refer) && (refer.ToString().Contains("/processing") ||refer.ToString().Contains("/recurring")|| refer.ToString().Contains("/succeeded") || refer.ToString().Contains("/deleted")))
34 | {
35 | builder.AppendLine(".table tbody { display:none; }");
36 | }
37 | }
38 | }
39 |
40 | return context.Response.WriteAsync(builder.ToString());
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Dashboard/Heartbeat/Dashboard/ContentDispatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Threading.Tasks;
4 | using Hangfire.Dashboard;
5 |
6 | namespace Hangfire.Heartbeat.Dashboard
7 | {
8 | internal class ContentDispatcher : IDashboardDispatcher
9 | {
10 | private static readonly Assembly ThisAssembly = typeof(ContentDispatcher).Assembly;
11 | private readonly string _contentType;
12 | private readonly string _resourceName;
13 | private readonly TimeSpan _expiresIn;
14 |
15 | public ContentDispatcher(string contentType, string resourceName, TimeSpan expiresIn)
16 | {
17 | _contentType = contentType;
18 | _resourceName = resourceName;
19 | _expiresIn = expiresIn;
20 | }
21 |
22 | public async Task Dispatch(DashboardContext context)
23 | {
24 | context.Response.ContentType = _contentType;
25 | context.Response.SetExpire(DateTimeOffset.UtcNow + _expiresIn);
26 |
27 | await WriteResourceAsync(context);
28 | }
29 |
30 | private async Task WriteResourceAsync(DashboardContext context)
31 | {
32 | using (var stream = ThisAssembly.GetManifestResourceStream(_resourceName))
33 | {
34 | if (stream == null)
35 | {
36 | context.Response.StatusCode = 404;
37 | }
38 | else
39 | {
40 | await stream.CopyToAsync(context.Response.Body);
41 | }
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Dashboard/Heartbeat/Dashboard/OverviewPage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Hangfire.Dashboard;
3 | using Hangfire.Dashboard.Pages;
4 |
5 | namespace Hangfire.Heartbeat.Dashboard
6 | {
7 | internal sealed class OverviewPage : RazorPage
8 | {
9 | private readonly HeartbeatDashboardOptions _dashboardOptions;
10 | public const string Title = "Heartbeat";
11 | public const string PageRoute = "/heartbeat";
12 | public const string StatsRoute = "/heartbeat/stats";
13 |
14 | private static readonly string PageHtml;
15 |
16 | static OverviewPage()
17 | {
18 | PageHtml = Utils.ReadStringResource("Hangfire.HttpJob.Dashboard.Heartbeat.Dashboard.html.OverviewPage.html");
19 | }
20 |
21 | public OverviewPage(HeartbeatDashboardOptions dashboardOptions)
22 | {
23 | _dashboardOptions = dashboardOptions ?? throw new ArgumentNullException(nameof(dashboardOptions));
24 | }
25 |
26 | public override void Execute()
27 | {
28 | WriteEmptyLine();
29 | Layout = new LayoutPage(Title);
30 | WriteLiteralLine(PageHtml);
31 | WriteEmptyLine();
32 | }
33 |
34 | private void WriteLiteralLine(string textToAppend)
35 | {
36 | WriteLiteral(textToAppend);
37 | WriteConfig();
38 | WriteLiteral("\r\n");
39 | }
40 |
41 | private void WriteConfig()
42 | {
43 | WriteLiteral($@"
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
CPU
10 |
11 |
12 |
13 |
RAM
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | PID |
33 | |
34 | Exec name |
35 | |
36 | |
37 | |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Hangfire.HttpJob.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | true
6 | httpjob for Hangfire(基于hangfire的webjob调度服务)
7 | https://github.com/yuzd/Hangfire.HttpJob
8 | 3.8.5
9 | yuzd
10 | 3.8.5.0
11 | 3.8.5.0
12 | true
13 | MIT
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | True
61 | True
62 | Strings.resx
63 |
64 |
65 | True
66 | True
67 | CronJobsPage.cshtml
68 |
69 |
70 |
71 |
72 |
73 | PublicResXFileCodeGenerator
74 | Strings.Designer.cs
75 |
76 |
77 |
78 |
79 |
80 | RazorGenerator
81 | CronJobsPage.generated.cs
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/PageDto.cs:
--------------------------------------------------------------------------------
1 | namespace Hangfire.HttpJob
2 | {
3 | public class PageDto
4 | {
5 | public int PageNo { get; set; }
6 |
7 | public int PageSize { get; set; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Server/HangfireHttpClientFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Net.Http;
6 | using HttpClientFactory;
7 | using HttpClientFactory.Impl;
8 |
9 | namespace Hangfire.HttpJob.Server
10 | {
11 | public class HangfireHttpClientFactory:PerHostHttpClientFactory
12 | {
13 | private readonly TimeSpan _timeOut;
14 | private readonly string _contentType;
15 | ///
16 | /// httpjob的请求处理
17 | ///
18 | internal static IHttpClientFactory HttpJobInstance;
19 | ///
20 | /// 钉钉的请求发送
21 | ///
22 | internal static IHttpClientFactory DingTalkInstance;
23 |
24 | ///
25 | /// 设置httpclientFactory来处理HttpClient请求
26 | ///
27 | ///
28 | public static void SetDefaultHttpJobInstance(IHttpClientFactory factory = null)
29 | {
30 | HttpJobInstance = factory ?? new HangfireHttpClientFactory(TimeSpan.FromHours(1),null);//这里设置1小时 是为了取消HttpClient自带的默认超时100s的限制 会在业务逻辑里面设使用实际的Timeout
31 | }
32 |
33 | ///
34 | /// 设置httpclientFactory来处理HttpClient请求
35 | ///
36 | ///
37 | public static void SetDefaultDingTalkInstance(IHttpClientFactory factory = null)
38 | {
39 | DingTalkInstance = factory?? new HangfireHttpClientFactory(TimeSpan.FromSeconds(60), "application/json;charset=UTF-8");
40 | }
41 |
42 |
43 | public HangfireHttpClientFactory(TimeSpan timeOut,string contentType)
44 | {
45 | _timeOut = timeOut;
46 | _contentType = contentType;
47 | }
48 |
49 |
50 | protected override HttpClient CreateHttpClient(HttpMessageHandler handler)
51 | {
52 | var client = new HttpClient(handler);
53 | client.DefaultRequestHeaders.ConnectionClose = false;
54 | client.DefaultRequestHeaders.Add("UserAgent", "Hangfire.HttpClient");
55 | client.Timeout = this._timeOut;
56 |
57 | if (!string.IsNullOrEmpty(_contentType))
58 | {
59 | client.DefaultRequestHeaders.TryAddWithoutValidation("content-type", _contentType);
60 | }
61 | return client;
62 | }
63 |
64 | protected override HttpMessageHandler CreateMessageHandler(string proxyUrl = null)
65 | {
66 | var handler = new HttpClientHandler();
67 | if (string.IsNullOrEmpty(proxyUrl))
68 | {
69 | handler.UseProxy = false;
70 | }
71 | else
72 | {
73 | handler.UseProxy = true;
74 | handler.Proxy = new WebProxy(proxyUrl);
75 | }
76 |
77 | handler.AllowAutoRedirect = false;
78 | handler.AutomaticDecompression = DecompressionMethods.None;
79 | handler.UseCookies = false;
80 | return handler;
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Server/Heartbeat/ConfigurationExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Hangfire.Annotations;
3 | using Hangfire.Dashboard;
4 | using Hangfire.Heartbeat.Dashboard;
5 |
6 | namespace Hangfire.Heartbeat
7 | {
8 | public static class ConfigurationExtensions
9 | {
10 | [PublicAPI]
11 | public static IGlobalConfiguration UseHeartbeatPage(this IGlobalConfiguration config, TimeSpan? checkInterval = null)
12 | {
13 | return UseHeartbeatPage(config, new HeartbeatDashboardOptions(checkInterval??TimeSpan.FromSeconds(1)));
14 | }
15 |
16 |
17 | [PublicAPI]
18 | public static IGlobalConfiguration UseHeartbeatPage(this IGlobalConfiguration config, HeartbeatDashboardOptions heartbeatDashboardOptions)
19 | {
20 | DashboardRoutes.Routes.AddRazorPage(OverviewPage.PageRoute, x => new OverviewPage(heartbeatDashboardOptions));
21 | NavigationMenu.Items.Add(page => new MenuItem(OverviewPage.Title, page.Url.To(OverviewPage.PageRoute))
22 | {
23 | Active = page.RequestPath.StartsWith(OverviewPage.PageRoute)
24 | });
25 | DashboardRoutes.Routes.Add(OverviewPage.StatsRoute, new UtilizationJsonDispatcher());
26 |
27 | DashboardRoutes.Routes.Add(
28 | "/heartbeat/jsknockout",
29 | new ContentDispatcher("application/javascript", "Hangfire.HttpJob.Dashboard.Heartbeat.Dashboard.js.knockout-3.4.2.js",
30 | TimeSpan.FromDays(30)));
31 |
32 | DashboardRoutes.Routes.Add(
33 | "/heartbeat/jsknockoutorderable",
34 | new ContentDispatcher("application/javascript", "Hangfire.HttpJob.Dashboard.Heartbeat.Dashboard.js.knockout.bindings.orderable.js",
35 | TimeSpan.FromDays(30)));
36 |
37 | DashboardRoutes.Routes.Add(
38 | "/heartbeat/jsnumeral",
39 | new ContentDispatcher("application/javascript", "Hangfire.HttpJob.Dashboard.Heartbeat.Dashboard.js.numeral.min.js", TimeSpan.FromDays(30)));
40 |
41 | DashboardRoutes.Routes.Add(
42 | "/heartbeat/jspage",
43 | new ContentDispatcher("application/javascript", "Hangfire.HttpJob.Dashboard.Heartbeat.Dashboard.js.OverviewPage.js", TimeSpan.FromSeconds(1)));
44 |
45 | DashboardRoutes.Routes.Add(
46 | "/heartbeat/cssstyles",
47 | new ContentDispatcher("text/css", "Hangfire.HttpJob.Dashboard.Heartbeat.Dashboard.css.styles.css", TimeSpan.FromSeconds(1)));
48 |
49 | return config;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Server/Heartbeat/HeartbeatDashboardOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.Heartbeat
4 | {
5 | ///
6 | /// Contains initialization options for Hangfire Dashboard UI.
7 | ///
8 | public sealed class HeartbeatDashboardOptions
9 | {
10 | ///
11 | /// Status polling interval.
12 | ///
13 | public TimeSpan CheckInterval { get; }
14 |
15 | ///
16 | /// Creates new options.
17 | ///
18 | /// Status polling interval.
19 | public HeartbeatDashboardOptions(TimeSpan checkInterval)
20 | {
21 | if (checkInterval == TimeSpan.Zero) throw new ArgumentException("Check interval must be nonzero value.", nameof(checkInterval));
22 | if (checkInterval != checkInterval.Duration()) throw new ArgumentException("Check interval must be positive value.", nameof(checkInterval));
23 |
24 | CheckInterval = checkInterval;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Server/Heartbeat/HeartbeatProcessMonitorOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.Heartbeat
4 | {
5 | ///
6 | /// Contains initialization options for Hangfire Dashboard UI.
7 | ///
8 | public sealed class HeartbeatProcessMonitorOptions
9 | {
10 | ///
11 | /// Status polling interval.
12 | ///
13 | public TimeSpan CheckInterval { get; }
14 |
15 | ///
16 | /// Creates new options.
17 | ///
18 | /// Status polling interval.
19 | public HeartbeatProcessMonitorOptions(TimeSpan checkInterval)
20 | {
21 | if (checkInterval == TimeSpan.Zero) throw new ArgumentException("Check interval must be nonzero value.", nameof(checkInterval));
22 | if (checkInterval != checkInterval.Duration()) throw new ArgumentException("Check interval must be positive value.", nameof(checkInterval));
23 |
24 | CheckInterval = checkInterval;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Server/Heartbeat/ProcessInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Hangfire.Heartbeat.Server
4 | {
5 | internal class ProcessInfo
6 | {
7 | public int Id { get; set; }
8 | public string Server { get; set; }
9 | public string ProcessName { get; set; }
10 | public double CpuUsage { get; set; }
11 | public long WorkingSet { get; set; }
12 | public long DiskUsage { get; set; }
13 | public DateTimeOffset Timestamp { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Server/Heartbeat/Utils.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Resources;
3 |
4 | namespace Hangfire.Heartbeat
5 | {
6 | internal static class Utils
7 | {
8 | public static string ReadStringResource(string resourceName)
9 | {
10 | var assembly = typeof(Utils).Assembly;
11 | using (var stream = assembly.GetManifestResourceStream(resourceName))
12 | {
13 | if (stream == null) throw new MissingManifestResourceException($"Cannot find resource {resourceName}");
14 |
15 | using (var reader = new StreamReader(stream))
16 | {
17 | return reader.ReadToEnd();
18 | }
19 | }
20 | }
21 |
22 | public static string FormatKey(string serverId) => "utilization:" + serverId;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Support/CompositeDispatcher.cs:
--------------------------------------------------------------------------------
1 | using Hangfire.Dashboard;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Threading.Tasks;
5 |
6 | namespace Hangfire.HttpJob.Support
7 | {
8 | ///
9 | /// Dispatcher that combines output from several other dispatchers.
10 | /// Used internally by .
11 | ///
12 | internal class CompositeDispatcher : IDashboardDispatcher
13 | {
14 | private readonly List _dispatchers;
15 |
16 | public CompositeDispatcher(params IDashboardDispatcher[] dispatchers)
17 | {
18 | _dispatchers = new List(dispatchers);
19 | }
20 |
21 | public void AddDispatcher(IDashboardDispatcher dispatcher)
22 | {
23 | if (dispatcher == null)
24 | throw new ArgumentNullException(nameof(dispatcher));
25 |
26 | _dispatchers.Add(dispatcher);
27 | }
28 |
29 | public async Task Dispatch(DashboardContext context)
30 | {
31 | if (context == null)
32 | throw new ArgumentNullException(nameof(context));
33 |
34 | if (_dispatchers.Count == 0)
35 | throw new InvalidOperationException("CompositeDispatcher should contain at least one dispatcher");
36 |
37 | foreach (var dispatcher in _dispatchers)
38 | {
39 | await dispatcher.Dispatch(context);
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Support/EmbeddedResourceDispatcher.cs:
--------------------------------------------------------------------------------
1 | using Hangfire.Dashboard;
2 | using System;
3 | using System.Reflection;
4 | using System.Threading.Tasks;
5 |
6 | namespace Hangfire.HttpJob.Support
7 | {
8 | ///
9 | /// Alternative to built-in EmbeddedResourceDispatcher, which (for some reasons) is not public.
10 | ///
11 | internal class EmbeddedResourceDispatcher : IDashboardDispatcher
12 | {
13 | private readonly Assembly _assembly;
14 | private readonly string _resourceName;
15 | private readonly string _contentType;
16 |
17 | public EmbeddedResourceDispatcher(Assembly assembly, string resourceName, string contentType = null)
18 | {
19 | if (assembly == null)
20 | throw new ArgumentNullException(nameof(assembly));
21 | if (string.IsNullOrEmpty(resourceName))
22 | throw new ArgumentNullException(nameof(resourceName));
23 |
24 | _assembly = assembly;
25 | _resourceName = resourceName;
26 | _contentType = contentType;
27 | }
28 |
29 | public async Task Dispatch(DashboardContext context)
30 | {
31 | if (!string.IsNullOrEmpty(_contentType))
32 | {
33 | var contentType = context.Response.ContentType;
34 |
35 | if (string.IsNullOrEmpty(contentType))
36 | {
37 | // content type not yet set
38 | context.Response.ContentType = _contentType;
39 | }
40 | else if (contentType != _contentType)
41 | {
42 | // content type already set, but doesn't match ours
43 | throw new InvalidOperationException($"ContentType '{_contentType}' conflicts with '{context.Response.ContentType}'");
44 | }
45 | }
46 |
47 | await WriteResourceAsync(context.Response, _assembly, _resourceName);
48 | }
49 |
50 | private static async Task WriteResourceAsync(DashboardResponse response, Assembly assembly, string resourceName)
51 | {
52 | using (var stream = assembly.GetManifestResourceStream(resourceName))
53 | {
54 | if (stream == null)
55 | throw new ArgumentException($@"Resource '{resourceName}' not found in assembly {assembly}.");
56 |
57 | await stream.CopyToAsync(response.Body);
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Support/ErrorState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Hangfire.Common;
5 | using Hangfire.States;
6 | using Newtonsoft.Json;
7 |
8 | namespace Hangfire.HttpJob.Support
9 | {
10 | internal class ErrorState:IState
11 | {
12 | public static readonly string StateName = "Failed";
13 | private readonly string _title;
14 |
15 | public ErrorState(string err,string title = "HttpJob")
16 | {
17 | FailedAt = DateTime.UtcNow;
18 | Reason = err;
19 | _title = string.IsNullOrEmpty(title) ? "HttpJob" : title;
20 | }
21 |
22 | [JsonIgnore]
23 | public DateTime FailedAt { get; set; }
24 |
25 | [JsonIgnore]
26 | public string Name => StateName;
27 |
28 | public Dictionary SerializeData()
29 | {
30 | return new Dictionary
31 | {
32 | { "FailedAt", JobHelper.SerializeDateTime(FailedAt) },
33 | { "ExceptionType", _title },
34 | { "ExceptionMessage", Reason },
35 | { "ExceptionDetails", ""}
36 | };
37 | }
38 |
39 | public string Reason { get; set; }
40 |
41 |
42 | [JsonIgnore]
43 | public bool IsFinal => false;
44 | [JsonIgnore]
45 | public bool IgnoreJobLoadException => false;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Support/HtmlHelperExtensions.cs:
--------------------------------------------------------------------------------
1 | using Hangfire.Dashboard;
2 | using System;
3 | using System.Reflection;
4 |
5 | namespace Hangfire.HttpJob.Support
6 | {
7 | ///
8 | /// Provides extension methods for .
9 | ///
10 | internal static class HtmlHelperExtensions
11 | {
12 | private static readonly FieldInfo _page = typeof(HtmlHelper).GetTypeInfo().GetDeclaredField(nameof(_page));
13 |
14 | ///
15 | /// Returs a associated with .
16 | ///
17 | /// Helper
18 | public static RazorPage GetPage(this HtmlHelper helper)
19 | {
20 | if (helper == null)
21 | throw new ArgumentNullException(nameof(helper));
22 |
23 | return (RazorPage)_page.GetValue(helper);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Support/HttpJobDisplayNameAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Text;
6 | using Hangfire.Common;
7 | using Hangfire.Dashboard;
8 | using Hangfire.HttpJob.Server;
9 |
10 | namespace Hangfire.HttpJob.Support
11 | {
12 | class HttpJobDisplayNameAttribute: JobDisplayNameAttribute
13 | {
14 |
15 | public override string Format(DashboardContext context, Job job)
16 | {
17 | var data = job.Args.FirstOrDefault() as HttpJobItem;
18 | if (data == null) return job.Method.Name;
19 | try
20 | {
21 | if (string.IsNullOrEmpty(data.RecurringJobIdentifier)) data.RecurringJobIdentifier = data.JobName;
22 |
23 | //增加别名
24 | if (!string.IsNullOrEmpty(data.AgentClass))
25 | {
26 | return "Agent:"+data.AgentClass+ ",Queue:" + data.QueueName + ",Retry:" + (data.EnableRetry) + "|" + data.AgentClass.Split(',')[0].Split('.').Last()+(!data.RecurringJobIdentifier.Equals(data.JobName)? "|" + data.JobName:"|")+"|"+ data.GetUrlHost();
27 | }
28 |
29 | var name = (data.Url.Split('/').LastOrDefault() ?? data.JobName);
30 | return data.Url.Replace("|","").Replace("\"","“").Replace("'","’") + ",Queue:" + data.QueueName + ",Retry:" + (data.EnableRetry) + "|" + name + (!data.JobName.Equals(name) ?"|" + data.JobName :"|") + "|"+ data.GetUrlHost();
31 | }
32 | catch (Exception)
33 | {
34 | return data.JobName;
35 | }
36 | }
37 |
38 | public HttpJobDisplayNameAttribute(string displayName) : base(displayName)
39 | {
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Support/HttpStatusCodeException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net;
4 | using System.Text;
5 | using Hangfire.HttpJob.Content.resx;
6 |
7 | namespace Hangfire.HttpJob.Support
8 | {
9 | public class HttpStatusCodeException:Exception
10 | {
11 | public string Msg { get; set; }
12 | public bool IsEl { get; set; }
13 | public string El { get; set; }
14 | public HttpStatusCodeException(HttpStatusCode code,string data):base($"{Strings.ResponseCode}:{code} ===> CheckResult: Fail ")
15 | {
16 | Msg = data;
17 | }
18 |
19 | public HttpStatusCodeException(string el, string data) : base($"{Strings.CallbackELExcuteError}:{el} ===> CheckResult: Fail ")
20 | {
21 | IsEl = true;
22 | El = el;
23 | Msg = data;
24 | }
25 | }
26 |
27 | public class CallbackJobException:Exception
28 | {
29 | public CallbackJobException(string code):base($"{Strings.CallbackFail} ===> {code} ")
30 | {
31 |
32 | }
33 | }
34 |
35 | public class AgentJobException : Exception
36 | {
37 | public AgentJobException(string agentClass,string err) : base($"AgentClass:"+ agentClass + "=>" + err)
38 | {
39 |
40 | }
41 | }
42 |
43 | public class HangfireServerShutDownError : Exception
44 | {
45 | public HangfireServerShutDownError():this("hangfire server was shut down!")
46 | {
47 |
48 | }
49 | public HangfireServerShutDownError(string msg):base(msg)
50 | {
51 |
52 | }
53 | }
54 |
55 | public class HangfireAgentShutDownError : Exception
56 | {
57 | public HangfireAgentShutDownError() : this("hangfire agent was shut down!")
58 | {
59 |
60 | }
61 | public HangfireAgentShutDownError(string msg) : base(msg)
62 | {
63 |
64 | }
65 | }
66 |
67 | public class HangfireAgentShutDownCauseJobRequeue : Exception
68 | {
69 |
70 | public HangfireAgentShutDownCauseJobRequeue(string msg) : base("hangfire agent was shut down! the processing job requeue:" + msg)
71 | {
72 |
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Support/QueueProviderFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Hangfire.Common;
4 | using Hangfire.HttpJob.Server;
5 |
6 | namespace Hangfire.HttpJob.Support
7 | {
8 | ///
9 | /// 自定义queue名称
10 | ///
11 | public class QueueProviderFilter : IJobFilterProvider
12 | {
13 | public IEnumerable GetFilters(Job job)
14 | {
15 | var arg = job.Args.FirstOrDefault() as HttpJobItem;
16 | if (arg == null || string.IsNullOrEmpty(arg.QueueName)) return new Common.JobFilter[] { };
17 |
18 |
19 | return new[]
20 | {
21 | new Common.JobFilter(
22 | new QueueAttribute(arg.QueueName.ToLower()),
23 | JobFilterScope.Method, null
24 | )
25 | };
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Server/Hangfire.HttpJob/Support/UrlUtil.cs:
--------------------------------------------------------------------------------
1 | using Hangfire.Dashboard;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace Hangfire.HttpJob.Support
7 | {
8 | ///
9 | /// Url工具类
10 | ///
11 | public static class UrlUtil
12 | {
13 | ///
14 | /// 获取hangfire服务器url地址(解决hangfire部署后带前缀PrefixPath,后部分url路径问题)
15 | /// 域名无前缀路径:http://domain.com/hangfire
16 | /// 域名无前缀路径:http://domain.com/{PrefixPath}/hangfire
17 | ///
18 | ///
19 | ///
20 | public static string GetCurrentHangfireUrl(this DashboardContext context)
21 | {
22 | var hangfireUrl = context.Request.PathBase;
23 | if (!string.IsNullOrEmpty(context.Options.PrefixPath))
24 | {
25 | hangfireUrl = context.Options.PrefixPath + context.Request.PathBase;
26 | }
27 | return hangfireUrl;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Test/Hangfire.HttpJob.Client.Test/Hangfire.HttpJob.Client.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/.dockerignore:
--------------------------------------------------------------------------------
1 | **/AntDeploy.json
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
2 | COPY . /publish
3 | WORKDIR /publish
4 | ENV ASPNETCORE_URLS=http://*:5000
5 | EXPOSE 5000
6 | ENTRYPOINT ["dotnet", "MemoryHangfire.dll"]
7 | # server_port@80@
8 | # volume@/opt/hangfire/logs:/publish/Logs@
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/MemoryHangfire.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
10 | true
11 | PreserveNewest
12 | PreserveNewest
13 |
14 |
15 | true
16 | Always
17 | PreserveNewest
18 |
19 |
20 | true
21 | Always
22 | PreserveNewest
23 |
24 |
25 |
26 |
27 |
28 | Always
29 |
30 |
31 | Always
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/NLog.Config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 | using NLog.Web;
6 |
7 | namespace MemoryHangfire
8 | {
9 | class Program
10 | {
11 | static void Main(string[] args)
12 | {
13 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.Config").GetCurrentClassLogger();
14 | try
15 | {
16 | logger.Debug("init main");
17 | CreateHostBuilder(args).Build().Run();
18 | }
19 | catch (Exception ex)
20 | {
21 | //NLog: catch setup errors
22 | logger.Error(ex, "Stopped program because of exception");
23 | throw;
24 | }
25 | finally
26 | {
27 | // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
28 | NLog.LogManager.Shutdown();
29 | }
30 | }
31 |
32 | public static IHostBuilder CreateHostBuilder(string[] args) =>
33 | Host.CreateDefaultBuilder(args)
34 | .ConfigureWebHostDefaults(webBuilder =>
35 | {
36 | webBuilder.UseStartup()
37 | .ConfigureLogging(logging =>
38 | {
39 | logging.ClearProviders();
40 | #if DEBUG
41 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
42 |
43 | #else
44 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Warning);
45 | #endif
46 | }).UseNLog();
47 | });
48 | }
49 | }
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/Startup.cs:
--------------------------------------------------------------------------------
1 | using Hangfire;
2 | using Hangfire.Console;
3 | using Hangfire.Dashboard.BasicAuthorization;
4 | using Hangfire.HttpJob;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.AspNetCore.Http;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Logging;
11 | using NLog.Extensions.Logging;
12 | using System;
13 | using System.Collections.Generic;
14 | using System.Data;
15 | using Hangfire.Heartbeat;
16 | using Hangfire.Heartbeat.Server;
17 | using Hangfire.Tags;
18 | using Microsoft.AspNetCore.Localization;
19 | using Microsoft.Extensions.Hosting;
20 | using Newtonsoft.Json;
21 | using IsolationLevel = System.Transactions.IsolationLevel;
22 |
23 | namespace MemoryHangfire
24 | {
25 | public class Startup
26 | {
27 | public Startup(IConfiguration configuration)
28 | {
29 | JsonConfig = configuration;
30 | }
31 |
32 | public IConfiguration JsonConfig { get; }
33 |
34 |
35 | public void ConfigureServices(IServiceCollection services)
36 | {
37 | services.AddSelfHangfire(JsonConfig);
38 | }
39 |
40 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory logging)
41 | {
42 | app.ConfigureSelfHangfire(JsonConfig);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Error",
6 | "System": "Error",
7 | "Microsoft": "Error"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "Hangfire": {
11 | "HangfireSettings": {
12 | "ServerName": "MemoryHangfire",
13 | "TablePrefix": "hangfire",
14 | "StartUpPath": "/job",
15 | "ReadOnlyPath": "",
16 | "JobQueues": [ "default", "apis", "recurring" ],
17 | "WorkerCount": 50,
18 | "DisplayStorageConnectionString": false,
19 | "HttpAuthInfo": {
20 | "SslRedirect": false,
21 | "RequireSsl": false,
22 | "LoginCaseSensitive": true,
23 | "IsOpenLogin": true,
24 | "Users": [
25 | {
26 | "Login": "admin",
27 | "PasswordClear": "test"
28 | }
29 | ]
30 | }
31 | },
32 | "HttpJobOptions": {
33 | "Lang": "zh",
34 | "DefaultTimeZone": "",
35 | "CurrentDomain": "//",
36 | "EnableDingTalk": true,
37 | "DefaultRecurringQueueName": "recurring",
38 | "GlobalSettingJsonFilePath": "",
39 | "Proxy": "",
40 | "JobExpirationTimeoutDay": 7,
41 | "GlobalHttpTimeOut": 5000,
42 | "MailOption": {
43 | "Server": "",
44 | "Port": 0,
45 | "User": "",
46 | "Password": "",
47 | "UseSsl": false,
48 | "AlertMailList": []
49 | },
50 | "DingTalkOption": {
51 | "Token": "",
52 | "AtPhones": "",
53 | "IsAtAll": false
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Test/MemoryHangfire/MemoryHangfire/hangfire/hangfire_global.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/.dockerignore:
--------------------------------------------------------------------------------
1 | **/AntDeploy.json
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
2 | COPY . /publish
3 | WORKDIR /publish
4 | ENV ASPNETCORE_URLS=http://*:5000
5 | EXPOSE 5000
6 | ENTRYPOINT ["dotnet", "PostgreSqlHangfire.dll"]
7 | # server_port@80@
8 | # volume@/opt/hangfire/logs:/publish/Logs@
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/NLog.Config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/PostgreSqlHangfire.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Always
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Always
32 |
33 |
34 |
35 |
36 |
37 | Always
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Hosting;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using NLog.Web;
10 |
11 | namespace PostgreSqlHangfire
12 | {
13 | public class Program
14 | {
15 | public static void Main(string[] args)
16 | {
17 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.Config").GetCurrentClassLogger();
18 | try
19 | {
20 | logger.Debug("init main");
21 | CreateHostBuilder(args).Build().Run();
22 | }
23 | catch (Exception ex)
24 | {
25 | //NLog: catch setup errors
26 | logger.Error(ex, "Stopped program because of exception");
27 | throw;
28 | }
29 | finally
30 | {
31 | // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
32 | NLog.LogManager.Shutdown();
33 | }
34 | }
35 |
36 | public static IHostBuilder CreateHostBuilder(string[] args) =>
37 | Host.CreateDefaultBuilder(args)
38 | .ConfigureWebHostDefaults(webBuilder =>
39 | {
40 | webBuilder.UseStartup()
41 | .ConfigureLogging(logging =>
42 | {
43 | logging.ClearProviders();
44 | #if DEBUG
45 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
46 |
47 | #else
48 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Warning);
49 | #endif
50 | }).UseNLog();
51 | });
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:1945",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "PostgreSqlHangfire": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.AspNetCore.Http;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Hosting;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Threading.Tasks;
10 | using Microsoft.Extensions.Configuration;
11 | using Microsoft.Extensions.Logging;
12 |
13 | namespace PostgreSqlHangfire
14 | {
15 | public class Startup
16 | {
17 | public Startup(IConfiguration configuration)
18 | {
19 | JsonConfig = configuration;
20 | }
21 |
22 | public IConfiguration JsonConfig { get; }
23 |
24 |
25 | public void ConfigureServices(IServiceCollection services)
26 | {
27 | services.AddSelfHangfire(JsonConfig);
28 | }
29 |
30 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory logging)
31 | {
32 | app.ConfigureSelfHangfire(JsonConfig);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "Hangfire": {
11 | "HangfireSettings": {
12 | "ServerName": "PostgreSqlHangfire",
13 | "TablePrefix": "",
14 | "StartUpPath": "/job",
15 | "ReadOnlyPath": "",
16 | "JobQueues": [ "default", "apis", "recurring" ],
17 | "WorkerCount": 50,
18 | "DisplayStorageConnectionString": false,
19 | "HttpAuthInfo": {
20 | "SslRedirect": false,
21 | "RequireSsl": false,
22 | "LoginCaseSensitive": true,
23 | "IsOpenLogin": true,
24 | "Users": [
25 | {
26 | "Login": "admin",
27 | "PasswordClear": "test"
28 | }
29 | ]
30 | },
31 | "ConnectionString": "Server=localhost;Port=5432;Database=hangfire;User Id=postgres;Password=postgres;"
32 | },
33 | "HttpJobOptions": {
34 | "Lang": "zh",
35 | "DefaultTimeZone": "",
36 | "CurrentDomain": "//",
37 | "EnableDingTalk": true,
38 | "DefaultRecurringQueueName": "recurring",
39 | "GlobalSettingJsonFilePath": "",
40 | "Proxy": "",
41 | "JobExpirationTimeoutDay": 7,
42 | "GlobalHttpTimeOut": 5000,
43 | "MailOption": {
44 | "Server": "",
45 | "Port": 0,
46 | "User": "",
47 | "Password": "",
48 | "UseSsl": false,
49 | "AlertMailList": []
50 | },
51 | "DingTalkOption": {
52 | "Token": "",
53 | "AtPhones": "",
54 | "IsAtAll": false
55 | }
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/Test/PostgreSqlHangfire/hangfire/hangfire_global.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/Test/RedisHangfire/.dockerignore:
--------------------------------------------------------------------------------
1 | **/AntDeploy.json
--------------------------------------------------------------------------------
/Test/RedisHangfire/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
2 | COPY . /publish
3 | WORKDIR /publish
4 | ENV ASPNETCORE_URLS=http://*:5000
5 | EXPOSE 5000
6 | ENTRYPOINT ["dotnet", "RedisHangfire.dll"]
7 | # server_port@80@
8 | # volume@/opt/hangfire/logs:/publish/Logs@
--------------------------------------------------------------------------------
/Test/RedisHangfire/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Hosting;
10 | using Microsoft.Extensions.Logging;
11 |
12 | namespace RedisHangfire
13 | {
14 | public class Program
15 | {
16 | public static void Main(string[] args)
17 | {
18 | CreateHostBuilder(args).Build().Run();
19 | }
20 |
21 | public static IHostBuilder CreateHostBuilder(string[] args) =>
22 | Host.CreateDefaultBuilder(args)
23 | .ConfigureWebHostDefaults(webBuilder =>
24 | {
25 | webBuilder.UseStartup()
26 | .ConfigureLogging(logging =>
27 | {
28 | logging.ClearProviders();
29 |
30 | #if DEBUG
31 | logging.AddConsole();
32 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
33 |
34 | #else
35 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Warning);
36 | #endif
37 | });
38 | });
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Test/RedisHangfire/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:7911",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "RedisHangfire": {
19 | "commandName": "Project",
20 | "launchBrowser": false,
21 | "applicationUrl": "http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Test/RedisHangfire/RedisHangfire.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Always
26 |
27 |
28 |
29 |
30 |
31 | Always
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Test/RedisHangfire/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Hangfire;
7 | using Hangfire.Console;
8 | using Hangfire.Dashboard.BasicAuthorization;
9 | using Hangfire.Heartbeat;
10 | using Hangfire.Heartbeat.Server;
11 | using Hangfire.HttpJob;
12 | using Hangfire.Redis;
13 | using Microsoft.AspNetCore.Builder;
14 | using Microsoft.AspNetCore.Hosting;
15 | using Microsoft.AspNetCore.Http;
16 | using Microsoft.AspNetCore.Localization;
17 | using Microsoft.Extensions.Configuration;
18 | using Microsoft.Extensions.DependencyInjection;
19 | using Newtonsoft.Json;
20 | using StackExchange.Redis;
21 |
22 | namespace RedisHangfire
23 | {
24 | public class Startup
25 | {
26 | public IConfiguration JsonConfig { get; }
27 |
28 | public Startup(IConfiguration configuration)
29 | {
30 | JsonConfig = configuration;
31 | }
32 |
33 | // This method gets called by the runtime. Use this method to add services to the container.
34 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
35 | public void ConfigureServices(IServiceCollection services)
36 | {
37 | services.AddSelfHangfire(JsonConfig);
38 | }
39 |
40 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
41 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
42 | {
43 | app.ConfigureSelfHangfire(JsonConfig);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Test/RedisHangfire/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Test/RedisHangfire/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "Hangfire": {
11 | "HangfireSettings": {
12 | "ServerName": "RedisHangfire",
13 | "TablePrefix": "hangfire:",
14 | "StartUpPath": "/job",
15 | "ReadOnlyPath": "",
16 | "JobQueues": [ "default", "apis", "recurring" ],
17 | "WorkerCount": 50,
18 | "DisplayStorageConnectionString": false,
19 | "HttpAuthInfo": {
20 | "SslRedirect": false,
21 | "RequireSsl": false,
22 | "LoginCaseSensitive": true,
23 | "IsOpenLogin": true,
24 | "Users": [
25 | {
26 | "Login": "admin",
27 | "PasswordClear": "test"
28 | }
29 | ]
30 | },
31 | "ConnectionString": "127.0.0.1:6379"
32 | },
33 | "HttpJobOptions": {
34 | "Lang": "zh",
35 | "DefaultTimeZone": "",
36 | "CurrentDomain": "//",
37 | "EnableDingTalk": true,
38 | "DefaultRecurringQueueName": "recurring",
39 | "GlobalSettingJsonFilePath": "",
40 | "Proxy": "",
41 | "JobExpirationTimeoutDay": 7,
42 | "GlobalHttpTimeOut": 5000,
43 | "MailOption": {
44 | "Server": "",
45 | "Port": 0,
46 | "User": "",
47 | "Password": "",
48 | "UseSsl": false,
49 | "AlertMailList": []
50 | },
51 | "DingTalkOption": {
52 | "Token": "",
53 | "AtPhones": "",
54 | "IsAtAll": false
55 | }
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/Test/RedisHangfire/hangfire/hangfire_global.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/Test/TestHangfire/.dockerignore:
--------------------------------------------------------------------------------
1 | **/AntDeploy.json
--------------------------------------------------------------------------------
/Test/TestHangfire/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
2 | COPY . /publish
3 | WORKDIR /publish
4 | ENV ASPNETCORE_URLS=http://*:5000
5 | EXPOSE 5000
6 | ENTRYPOINT ["dotnet", "MysqlHangfire.dll"]
7 | # server_port@80@
8 | # volume@/opt/hangfire/logs:/publish/Logs@
--------------------------------------------------------------------------------
/Test/TestHangfire/MysqlHangfire.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Always
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | Always
46 |
47 |
48 |
49 |
50 |
51 | Always
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Test/TestHangfire/NLog.Config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Test/TestHangfire/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Hosting;
9 | using Microsoft.Extensions.Logging;
10 | using NLog.Web;
11 |
12 | namespace MysqlHangfire
13 | {
14 | public class Program
15 | {
16 | public static void Main(string[] args)
17 | {
18 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.Config").GetCurrentClassLogger();
19 | try
20 | {
21 | logger.Info("Starting jobagent host");
22 | CreateHostBuilder(args).Build().Run();
23 | }
24 | catch (Exception ex)
25 | {
26 | //NLog: catch setup errors
27 | logger.Error(ex, "Stopped program because of exception");
28 | throw;
29 | }
30 | finally
31 | {
32 | // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
33 | NLog.LogManager.Shutdown();
34 | }
35 | }
36 |
37 | public static IHostBuilder CreateHostBuilder(string[] args) =>
38 | Host.CreateDefaultBuilder(args)
39 | .ConfigureWebHostDefaults(webBuilder =>
40 | {
41 | webBuilder.UseStartup()
42 | .ConfigureLogging(logging =>
43 | {
44 | logging.ClearProviders();
45 | #if DEBUG
46 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
47 |
48 | #else
49 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Warning);
50 | #endif
51 | }).UseNLog();
52 | });
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Test/TestHangfire/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:12688",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "TestHangfire": {
19 | "commandName": "Project",
20 | "environmentVariables": {
21 | "ASPNETCORE_ENVIRONMENT": "Development"
22 | },
23 | "nativeDebugging": true,
24 | "applicationUrl": "http://localhost:5000"
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Test/TestHangfire/Startup.cs:
--------------------------------------------------------------------------------
1 | using Hangfire.Console;
2 | using Hangfire.Dashboard.BasicAuthorization;
3 | using Hangfire.HttpJob;
4 | using Microsoft.AspNetCore.Builder;
5 | using Microsoft.AspNetCore.Hosting;
6 | using Microsoft.AspNetCore.Http;
7 | using Microsoft.Extensions.Configuration;
8 | using Microsoft.Extensions.DependencyInjection;
9 | using Microsoft.Extensions.Logging;
10 | using NLog.Extensions.Logging;
11 | using System.Collections.Generic;
12 | using System.Data;
13 | using Hangfire.Heartbeat;
14 | using Hangfire.Heartbeat.Server;
15 | using Hangfire.Tags;
16 | using Microsoft.AspNetCore.Localization;
17 | using Microsoft.Extensions.Hosting;
18 | using Newtonsoft.Json;
19 | using IsolationLevel = System.Transactions.IsolationLevel;
20 |
21 | namespace MysqlHangfire
22 | {
23 | public class Startup
24 | {
25 | public Startup(IConfiguration configuration)
26 | {
27 | JsonConfig = configuration;
28 | }
29 |
30 | public IConfiguration JsonConfig { get; }
31 |
32 |
33 | public void ConfigureServices(IServiceCollection services)
34 | {
35 | services.AddSelfHangfire(JsonConfig);
36 | }
37 |
38 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory logging)
39 | {
40 | app.ConfigureSelfHangfire(JsonConfig);
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/Test/TestHangfire/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Error",
6 | "System": "Error",
7 | "Microsoft": "Error"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Test/TestHangfire/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "Hangfire": {
11 | "HangfireSettings": {
12 | "ServerName": "MysqlHangfire",
13 | "TablePrefix": "hangfire",
14 | "StartUpPath": "/job",
15 | "ReadOnlyPath": "",
16 | "JobQueues": [ "default", "apis", "recurring" ],
17 | "WorkerCount": 50,
18 | "DisplayStorageConnectionString": false,
19 | "HttpAuthInfo": {
20 | "SslRedirect": false,
21 | "RequireSsl": false,
22 | "LoginCaseSensitive": true,
23 | "IsOpenLogin": true,
24 | "Users": [
25 | {
26 | "Login": "admin",
27 | "PasswordClear": "test"
28 | }
29 | ]
30 | },
31 | "ConnectionString": "Server=localhost;Port=3306;Database=hangfire;Uid=root;Pwd=123456;charset=utf8;SslMode=none;Allow User Variables=True"
32 | },
33 | "HttpJobOptions": {
34 | "Lang": "zh",
35 | "DefaultTimeZone": "",
36 | "CurrentDomain": "//",
37 | "EnableDingTalk": true,
38 | "DefaultRecurringQueueName": "recurring",
39 | "GlobalSettingJsonFilePath": "",
40 | "Proxy": "",
41 | "JobExpirationTimeoutDay": 7,
42 | "GlobalHttpTimeOut": 5000,
43 | "MailOption": {
44 | "Server": "",
45 | "Port": 0,
46 | "User": "",
47 | "Password": "",
48 | "UseSsl": false,
49 | "AlertMailList": []
50 | },
51 | "DingTalkOption": {
52 | "Token": "",
53 | "AtPhones": "",
54 | "IsAtAll": false
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Test/TestHangfire/hangfire/hangfire_global.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/Test/TestHangfireAgent/Jobs/TestHangJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestHangfireAgent.Jobs
10 | {
11 | [HangJobUntilStop(RegisterName = "HangJob测试")]
12 | public class TestHangJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestHangJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestHangJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info(nameof(OnStart) + (jobContext.Param ?? string.Empty));
24 |
25 | while (!jobContext.CancelToken.IsCancellationRequested)
26 | {
27 | jobContext.Console.Info("dddd");
28 | await Task.Delay(1000 * 10);
29 | }
30 | jobContext.Console.Warning("game over");
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Test/TestHangfireAgent/Jobs/TestJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Hangfire.HttpJob.Agent.Util;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace TestHangfireAgent.Jobs
11 | {
12 | [SingletonJob(RegisterName = "单例job")]//不打这个标签也行 默认就是单例的
13 | public class TestJob : JobAgent
14 | {
15 | public TestJob(ILogger logger)
16 | {
17 | logger.LogInformation($"Create {nameof(TestJob)} Instance Success");
18 | }
19 | public override async Task OnStart(JobContext jobContext)
20 | {
21 | jobContext.Console.Info("info消息");
22 | jobContext.Console.Warning("waring消息");
23 | jobContext.Console.Error("error消息");
24 | jobContext.Console.Info("开始等待1秒");
25 | await Task.Delay(1000 * 1);
26 | jobContext.Console.Info("结束等待1秒");
27 | jobContext.Console.WriteLine("开始测试Progressbar",ConsoleFontColor.Cyan);
28 |
29 | var bar = jobContext.Console.WriteProgressBar("testbar");
30 | for (int i = 0; i < 10; i++)
31 | {
32 | bar.SetValue(i * 10);
33 | await Task.Delay(1000);
34 | }
35 | }
36 |
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Test/TestHangfireAgent/Jobs/TestTransientJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Hangfire.HttpJob.Agent;
7 | using Hangfire.HttpJob.Agent.Attribute;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace TestHangfireAgent.Jobs
11 | {
12 | [TransientJob(RegisterName = "多例job")]
13 | public class TestTransientJob:JobAgent
14 | {
15 | private readonly ILogger _logger;
16 |
17 | public TestTransientJob(ILogger logger)
18 | {
19 | _logger = logger;
20 | _logger.LogInformation($"Create {nameof(TestTransientJob)} Instance Success");
21 | }
22 | public override async Task OnStart(JobContext jobContext)
23 | {
24 | jobContext.Console.Warning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
25 | _logger.LogWarning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
26 | await Task.Delay(5000);
27 | _logger.LogWarning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
28 | jobContext.Console.Warning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
29 | }
30 |
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Test/TestHangfireAgent/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Hosting;
10 | using Microsoft.Extensions.Logging;
11 |
12 | namespace TestHangfireAgent
13 | {
14 | public class Program
15 | {
16 | public static void Main(string[] args)
17 | {
18 | CreateHostBuilder(args).Build().Run();
19 | }
20 | public static IHostBuilder CreateHostBuilder(string[] args) =>
21 | Host.CreateDefaultBuilder(args)
22 | .ConfigureWebHostDefaults(webBuilder =>
23 | {
24 | webBuilder.UseStartup()
25 | .ConfigureLogging(logging =>
26 | {
27 | logging.ClearProviders();
28 | #if DEBUG
29 | logging.AddConsole();
30 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
31 |
32 | #else
33 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
34 | #endif
35 | }).UseUrls("http://*:5002");
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Test/TestHangfireAgent/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:62813",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "TestHangfireAgent": {
19 | "commandName": "Project",
20 | "environmentVariables": {
21 | "ASPNETCORE_ENVIRONMENT": "Development"
22 | },
23 | "applicationUrl": "http://localhost:5000"
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/Test/TestHangfireAgent/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.MysqlConsole;
7 | using Microsoft.AspNetCore.Builder;
8 | using Microsoft.AspNetCore.Hosting;
9 | using Microsoft.AspNetCore.Http;
10 | using Microsoft.Extensions.DependencyInjection;
11 | using Microsoft.Extensions.Logging;
12 |
13 | namespace TestHangfireAgent
14 | {
15 | public class Startup
16 | {
17 | // This method gets called by the runtime. Use this method to add services to the container.
18 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
19 | public void ConfigureServices(IServiceCollection services)
20 | {
21 | services.AddHangfireJobAgent();
22 | }
23 |
24 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
25 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory logging)
26 | {
27 | app.UseHangfireJobAgent();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Test/TestHangfireAgent/TestHangfireAgent.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Always
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Test/TestHangfireAgent/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "JobAgent": {
11 | "Enabled": true,
12 | "SitemapUrl": "/jobagent",
13 | "EnabledBasicAuth": true,
14 | "BasicUserName": "admin",
15 | "BasicUserPwd": "123456",
16 | "EnableAutoRegister": true,
17 | "RegisterAgentHost": "http://localhost:5002",
18 | "RegisterHangfireUrl": "http://localhost:5000/job",
19 | "RegisterHangfireBasicName": "admin",
20 | "RegisterHangfireBasicPwd": "test"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Test/TestHangfirePostgreSqlAgent/Jobs/TestHangJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestHangfirePostgreSqlAgent.Jobs
10 | {
11 | [HangJobUntilStop(RegisterName = "HangJob测试")]
12 | public class TestHangJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestHangJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestHangJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info(nameof(OnStart) + (jobContext.Param ?? string.Empty));
24 |
25 | while (!jobContext.CancelToken.IsCancellationRequested)
26 | {
27 | jobContext.Console.Info("dddd");
28 | await Task.Delay(1000 * 10);
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Test/TestHangfirePostgreSqlAgent/Jobs/TestJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestHangfirePostgreSqlAgent.Jobs
10 | {
11 | [SingletonJob(RegisterName = "单例job")]//不打这个标签也行 默认就是单例的
12 | public class TestJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info("info消息");
24 | jobContext.Console.Warning("waring消息");
25 | jobContext.Console.Error("error消息");
26 | jobContext.Console.Info("开始等待1秒");
27 | await Task.Delay(1000 * 1);
28 | jobContext.Console.Info("结束等待1秒");
29 | jobContext.Console.WriteLine("开始测试Progressbar", ConsoleFontColor.Cyan);
30 |
31 | var bar = jobContext.Console.WriteProgressBar("testbar");
32 | for (int i = 0; i < 10; i++)
33 | {
34 | bar.SetValue(i * 10);
35 | await Task.Delay(1000);
36 | }
37 | }
38 |
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Test/TestHangfirePostgreSqlAgent/Jobs/TestTransientJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Hangfire.HttpJob.Agent;
7 | using Hangfire.HttpJob.Agent.Attribute;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace TestHangfirePostgreSqlAgent.Jobs
11 | {
12 | [TransientJob(RegisterName = "多例job")]
13 | public class TestTransientJob:JobAgent
14 | {
15 | private readonly ILogger _logger;
16 |
17 | public TestTransientJob(ILogger logger)
18 | {
19 | _logger = logger;
20 | _logger.LogInformation($"Create {nameof(TestTransientJob)} Instance Success");
21 | }
22 | public override async Task OnStart(JobContext jobContext)
23 | {
24 | jobContext.Console.Warning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
25 | _logger.LogWarning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
26 | await Task.Delay(5000);
27 | _logger.LogWarning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
28 | jobContext.Console.Warning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
29 | }
30 |
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Test/TestHangfirePostgreSqlAgent/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using Microsoft.AspNetCore.Hosting;
4 | using Microsoft.Extensions.Hosting;
5 | using Microsoft.Extensions.Logging;
6 |
7 | namespace TestHangfirePostgreSqlAgent
8 | {
9 | public class Program
10 | {
11 | public static void Main(string[] args)
12 | {
13 | CreateHostBuilder(args).Build().Run();
14 | }
15 | public static IHostBuilder CreateHostBuilder(string[] args) =>
16 | Host.CreateDefaultBuilder(args)
17 | .ConfigureWebHostDefaults(webBuilder =>
18 | {
19 | webBuilder.UseStartup()
20 | .ConfigureLogging(logging =>
21 | {
22 | logging.ClearProviders();
23 | #if DEBUG
24 | logging.AddConsole();
25 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
26 |
27 | #else
28 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
29 | #endif
30 | }).UseUrls("http://*:5002");
31 | });
32 |
33 |
34 | }
35 | }
--------------------------------------------------------------------------------
/Test/TestHangfirePostgreSqlAgent/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:65324/",
7 | "sslPort": 44357
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "TestHangfirePostgreSqlAgent": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "https://localhost:5001;http://localhost:5000"
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Test/TestHangfirePostgreSqlAgent/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.Extensions.DependencyInjection;
8 | using Hangfire.HttpJob.Agent.PostgreSqlConsole;
9 |
10 | namespace TestHangfirePostgreSqlAgent
11 | {
12 | public class Startup
13 | {
14 |
15 | // This method gets called by the runtime. Use this method to add services to the container.
16 | public void ConfigureServices(IServiceCollection services)
17 | {
18 | services.AddHangfireJobAgent();
19 | }
20 |
21 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
22 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
23 | {
24 | app.UseHangfireJobAgent();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Test/TestHangfirePostgreSqlAgent/TestHangfirePostgreSqlAgent.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Test/TestHangfirePostgreSqlAgent/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "JobAgent": {
11 | "Enabled": true,
12 | "SitemapUrl": "/jobagent",
13 | "EnabledBasicAuth": true,
14 | "BasicUserName": "admin",
15 | "BasicUserPwd": "123456",
16 | "EnableAutoRegister": true,
17 | "RegisterAgentHost": "http://localhost:5002",
18 | "RegisterHangfireUrl": "http://localhost:5000/job",
19 | "RegisterHangfireBasicName": "admin",
20 | "RegisterHangfireBasicPwd": "test"
21 | }
22 | }
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/Jobs/TestHangJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestHangfireRedisAgent.Jobs
10 | {
11 | [HangJobUntilStop(RegisterName = "HangJob测试")]
12 | public class TestHangJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestHangJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestHangJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info(nameof(OnStart) + (jobContext.Param ?? string.Empty));
24 |
25 | while (!jobContext.CancelToken.IsCancellationRequested)
26 | {
27 | jobContext.Console.Info("dddd");
28 | await Task.Delay(1000 * 10);
29 | }
30 | throw new Exception("dddddd");
31 | jobContext.Console.Warning("game over");
32 | }
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/Jobs/TestJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestHangfireRedisAgent.Jobs
10 | {
11 | [SingletonJob(RegisterName = "单例job")]//不打这个标签也行 默认就是单例的
12 | public class TestJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info("info消息");
24 | jobContext.Console.Warning("waring消息");
25 | jobContext.Console.Error("error消息");
26 | jobContext.Console.Info("开始等待1秒");
27 | await Task.Delay(1000 * 1);
28 | jobContext.Console.Info("结束等待1秒");
29 | jobContext.Console.WriteLine("开始测试Progressbar", ConsoleFontColor.Cyan);
30 |
31 | var bar = jobContext.Console.WriteProgressBar("testbar");
32 | for (int i = 0; i < 10; i++)
33 | {
34 | bar.SetValue(i * 10);
35 | await Task.Delay(1000);
36 | }
37 | }
38 |
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/Jobs/TestTransientJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Hangfire.HttpJob.Agent;
7 | using Hangfire.HttpJob.Agent.Attribute;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace TestHangfireRedisAgent.Jobs
11 | {
12 | [TransientJob(RegisterName = "多例job")]
13 | public class TestTransientJob:JobAgent
14 | {
15 | private readonly ILogger _logger;
16 |
17 | public TestTransientJob(ILogger logger)
18 | {
19 | _logger = logger;
20 | _logger.LogInformation($"Create {nameof(TestTransientJob)} Instance Success");
21 | }
22 | public override async Task OnStart(JobContext jobContext)
23 | {
24 | jobContext.Console.Warning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
25 | _logger.LogWarning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
26 | await Task.Delay(5000);
27 | _logger.LogWarning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
28 | jobContext.Console.Warning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
29 | }
30 |
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/NLog.Config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Hosting;
10 | using Microsoft.Extensions.Logging;
11 | using NLog.Web;
12 |
13 | namespace TestSqlserverHangfireAgent
14 | {
15 | public class Program
16 | {
17 | public static void Main(string[] args)
18 | {
19 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.Config").GetCurrentClassLogger();
20 | try
21 | {
22 | logger.Info("Starting jobagent host");
23 | CreateHostBuilder(args).Build().Run();
24 | }
25 | catch (Exception ex)
26 | {
27 | //NLog: catch setup errors
28 | logger.Error(ex, "Stopped program because of exception");
29 | throw;
30 | }
31 | finally
32 | {
33 | // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
34 | NLog.LogManager.Shutdown();
35 | }
36 | }
37 |
38 | public static IHostBuilder CreateHostBuilder(string[] args) =>
39 | Host.CreateDefaultBuilder(args)
40 | .ConfigureWebHostDefaults(webBuilder =>
41 | {
42 | webBuilder.UseStartup()
43 | .ConfigureLogging(logging =>
44 | {
45 | logging.ClearProviders();
46 | #if DEBUG
47 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
48 |
49 | #else
50 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
51 | #endif
52 | }).UseNLog().UseUrls("http://*:5002");
53 | });
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:10276",
7 | "sslPort": 44354
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "TestHangfireRedisAgent": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.RedisConsole;
7 | using Microsoft.AspNetCore.Builder;
8 | using Microsoft.AspNetCore.Hosting;
9 | using Microsoft.AspNetCore.Http;
10 | using Microsoft.Extensions.DependencyInjection;
11 | using Microsoft.Extensions.Logging;
12 | using NLog.Extensions.Logging;
13 |
14 | namespace TestSqlserverHangfireAgent
15 | {
16 | public class Startup
17 | {
18 | // This method gets called by the runtime. Use this method to add services to the container.
19 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
20 | public void ConfigureServices(IServiceCollection services)
21 | {
22 | services.AddHangfireJobAgent();
23 | }
24 |
25 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
26 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory logging)
27 | {
28 | app.UseHangfireJobAgent();
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/TestHangfireRedisAgent.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Always
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Test/TestHangfireRedisAgent/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "JobAgent": {
11 | "Enabled": true,
12 | "SitemapUrl": "/jobagent",
13 | "EnabledBasicAuth": true,
14 | "BasicUserName": "test",
15 | "BasicUserPwd": "123456",
16 | "EnableAutoRegister": true,
17 | "RegisterAgentHost": "http://localhost:5002",
18 | "RegisterHangfireUrl": "http://localhost:5000/job",
19 | "RegisterHangfireBasicName": "admin",
20 | "RegisterHangfireBasicPwd": "test"
21 | }
22 | }
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/Jobs/TestHangJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestOwinHangfireRedisAgent.Jobs
10 | {
11 | [HangJobUntilStop(true)]
12 | public class TestHangJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestHangJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestHangJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info(nameof(OnStart) + (jobContext.Param ?? string.Empty));
24 |
25 | while (!jobContext.CancelToken.IsCancellationRequested)
26 | {
27 | jobContext.Console.Info("dddd");
28 | await Task.Delay(1000 * 10);
29 | }
30 | throw new Exception("dddddd");
31 | jobContext.Console.Warning("game over");
32 | }
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/Jobs/TestJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestOwinHangfireRedisAgent.Jobs
10 | {
11 | public class TestJob : JobAgent
12 | {
13 | private readonly ILogger _logger;
14 |
15 | public TestJob(ILogger logger)
16 | {
17 | _logger = logger;
18 | _logger.LogInformation($"Create {nameof(TestJob)} Instance Success");
19 | }
20 | public override async Task OnStart(JobContext jobContext)
21 | {
22 |
23 | jobContext.Console.Info("info消息");
24 | jobContext.Console.Warning("waring消息");
25 | jobContext.Console.Error("error消息");
26 | jobContext.Console.Info("开始等待1秒");
27 | await Task.Delay(1000 * 1);
28 | jobContext.Console.Info("结束等待1秒");
29 | jobContext.Console.WriteLine("开始测试Progressbar", ConsoleFontColor.Cyan);
30 |
31 | var bar = jobContext.Console.WriteProgressBar("testbar");
32 | for (int i = 0; i < 10; i++)
33 | {
34 | bar.SetValue(i * 10);
35 | await Task.Delay(1000);
36 | }
37 | }
38 |
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/Jobs/TestTransientJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Hangfire.HttpJob.Agent;
7 | using Hangfire.HttpJob.Agent.Attribute;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace TestOwinHangfireRedisAgent.Jobs
11 | {
12 | [TransientJob]
13 | public class TestTransientJob:JobAgent
14 | {
15 | private readonly ILogger _logger;
16 |
17 | public TestTransientJob(ILogger logger)
18 | {
19 | _logger = logger;
20 | _logger.LogInformation($"Create {nameof(TestTransientJob)} Instance Success");
21 | }
22 | public override async Task OnStart(JobContext jobContext)
23 | {
24 | jobContext.Console.Warning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
25 | _logger.LogWarning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
26 | await Task.Delay(5000);
27 | _logger.LogWarning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
28 | jobContext.Console.Warning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
29 | }
30 |
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/NLog.Config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
15 |
16 |
17 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Microsoft.Owin;
7 | using Microsoft.Owin.Hosting;
8 |
9 | [assembly: OwinStartup(typeof(TestOwinHangfireRedisAgent.Startup))]
10 | namespace TestOwinHangfireRedisAgent
11 | {
12 | class Program
13 | {
14 | const string url = "http://localhost:5366";
15 | static void Main(string[] args)
16 | {
17 | using (WebApp.Start(url))
18 | {
19 | Console.WriteLine("Server started at:" + url);
20 | Console.ReadLine();
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("TestOwinHangfireRedisAgent")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TestOwinHangfireRedisAgent")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 会使此程序集中的类型
18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("bc8b9574-1c54-46fe-b2f0-c0aee74b5cff")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
33 | //通过使用 "*",如下所示:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Hangfire.HttpJob.Agent;
7 | using Hangfire.HttpJob.Agent.RedisConsole;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Logging;
11 | using NLog.Extensions.Logging;
12 | using Owin;
13 |
14 |
15 | namespace TestOwinHangfireRedisAgent
16 | {
17 | public class Startup
18 | {
19 | public void Configuration(IAppBuilder app)
20 | {
21 | NLog.LogManager.LoadConfiguration("NLog.Config");
22 |
23 | var builder = new ConfigurationBuilder();
24 | var localtion = Path.GetDirectoryName(typeof(Startup).Assembly.Location);
25 | var appsettingPath = Path.Combine(localtion, "appsettings.json");
26 | builder.AddJsonFile(appsettingPath);
27 | var configRoot = builder.Build();
28 |
29 |
30 | var services = new ServiceCollection()
31 | .AddLogging(loggingBuilder =>
32 | {
33 | // configure Logging with NLog
34 | loggingBuilder.ClearProviders();
35 | loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
36 | loggingBuilder.AddNLog(configRoot);
37 | });
38 |
39 |
40 | services.AddSingleton(configRoot);
41 | services.AddHangfireJobAgent();
42 | app.UseHangfireJobAgent(services);
43 | Console.WriteLine("owin job agent ....");
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Test/TestOwinHangfireRedisAgent/TestOwinHangfireRedisAgent/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "JobAgent": {
11 | "Enabled": true,
12 | "SitemapUrl": "/jobagent",
13 | "EnabledBasicAuth": true,
14 | "BasicUserName": "test",
15 | "BasicUserPwd": "123456"
16 | }
17 | }
--------------------------------------------------------------------------------
/Test/TestSqlserver/.dockerignore:
--------------------------------------------------------------------------------
1 | **/AntDeploy.json
--------------------------------------------------------------------------------
/Test/TestSqlserver/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
2 | COPY . /publish
3 | WORKDIR /publish
4 | ENV ASPNETCORE_URLS=http://*:5000
5 | EXPOSE 5000
6 | ENTRYPOINT ["dotnet", "SqlserverHangfire.dll"]
7 | # server_port@80@
8 | # volume@/opt/hangfire/logs:/publish/Logs@
--------------------------------------------------------------------------------
/Test/TestSqlserver/NLog.Config:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Test/TestSqlserver/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Hosting;
10 | using Microsoft.Extensions.Logging;
11 | using NLog.Web;
12 |
13 | namespace SqlserverHangfire
14 | {
15 | public class Program
16 | {
17 | public static void Main(string[] args)
18 | {
19 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.Config").GetCurrentClassLogger();
20 | try
21 | {
22 | logger.Debug("init main");
23 | CreateHostBuilder(args).Build().Run();
24 | }
25 | catch (Exception ex)
26 | {
27 | //NLog: catch setup errors
28 | logger.Error(ex, "Stopped program because of exception");
29 | throw;
30 | }
31 | finally
32 | {
33 | // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
34 | NLog.LogManager.Shutdown();
35 | }
36 | }
37 |
38 | public static IHostBuilder CreateHostBuilder(string[] args) =>
39 | Host.CreateDefaultBuilder(args)
40 | .ConfigureWebHostDefaults(webBuilder =>
41 | {
42 | webBuilder.UseStartup()
43 | .ConfigureLogging(logging =>
44 | {
45 | logging.ClearProviders();
46 | #if DEBUG
47 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
48 |
49 | #else
50 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Warning);
51 | #endif
52 | }).UseNLog();
53 | });
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Test/TestSqlserver/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true
5 | },
6 | "profiles": {
7 | "TestSqlserver": {
8 | "commandName": "Project",
9 | "launchBrowser": false,
10 | "applicationUrl": "http://localhost:5000",
11 | "environmentVariables": {
12 | "ASPNETCORE_ENVIRONMENT": "Development"
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Test/TestSqlserver/SqlserverHangfire.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | InProcess
6 | SqlserverHangfire
7 | SqlserverHangfire
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Always
25 |
26 |
27 | Always
28 |
29 |
30 |
31 |
32 |
33 | Always
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Test/TestSqlserver/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire;
6 | using Hangfire.Console;
7 | using Hangfire.Dashboard.BasicAuthorization;
8 | using Hangfire.Heartbeat;
9 | using Hangfire.Heartbeat.Server;
10 | using Hangfire.HttpJob;
11 | using Hangfire.SqlServer;
12 | using Hangfire.Tags;
13 | using Hangfire.Tags.SqlServer;
14 | using Microsoft.AspNetCore.Builder;
15 | using Microsoft.AspNetCore.Hosting;
16 | using Microsoft.AspNetCore.Http;
17 | using Microsoft.AspNetCore.Localization;
18 | using Microsoft.Extensions.Configuration;
19 | using Microsoft.Extensions.DependencyInjection;
20 | using Microsoft.Extensions.Logging;
21 | using NLog.Extensions.Logging;
22 |
23 | namespace SqlserverHangfire
24 | {
25 | public class Startup
26 | {
27 | public Startup(IConfiguration configuration)
28 | {
29 | JsonConfig = configuration;
30 | }
31 |
32 | public IConfiguration JsonConfig { get; }
33 | // This method gets called by the runtime. Use this method to add services to the container.
34 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
35 | public void ConfigureServices(IServiceCollection services)
36 | {
37 | services.AddSelfHangfire(JsonConfig);
38 | }
39 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
40 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory logging)
41 | {
42 | app.ConfigureSelfHangfire(JsonConfig);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Test/TestSqlserver/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Test/TestSqlserver/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "Hangfire": {
11 | "HangfireSettings": {
12 | "ServerName": "SqlserverHangfire",
13 | "StartUpPath": "/job",
14 | "ReadOnlyPath": "",
15 | "JobQueues": [ "default", "apis", "recurring" ],
16 | "WorkerCount": 50,
17 | "DisplayStorageConnectionString": false,
18 | "HttpAuthInfo": {
19 | "SslRedirect": false,
20 | "RequireSsl": false,
21 | "LoginCaseSensitive": true,
22 | "IsOpenLogin": true,
23 | "Users": [
24 | {
25 | "Login": "admin",
26 | "PasswordClear": "test"
27 | }
28 | ]
29 | },
30 | "ConnectionString": "Server=.\\;Database=hangfire;Trusted_Connection=True;Enlist=False;"
31 | },
32 | "HttpJobOptions": {
33 | "Lang": "zh",
34 | "DefaultTimeZone": "",
35 | "CurrentDomain": "//",
36 | "EnableDingTalk": true,
37 | "DefaultRecurringQueueName": "recurring",
38 | "GlobalSettingJsonFilePath": "",
39 | "Proxy": "",
40 | "JobExpirationTimeoutDay": 7,
41 | "GlobalHttpTimeOut": 5000,
42 | "MailOption": {
43 | "Server": "",
44 | "Port": 0,
45 | "User": "",
46 | "Password": "",
47 | "UseSsl": false,
48 | "AlertMailList": []
49 | },
50 | "DingTalkOption": {
51 | "Token": "",
52 | "AtPhones": "",
53 | "IsAtAll": false
54 | }
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/Test/TestSqlserver/hangfire/hangfire_global.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/Test/TestSqlserverHangfireAgent/Jobs/TestHangJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestSqlserverHangfireAgent.Jobs
10 | {
11 | [HangJobUntilStop(RegisterName = "HangJob测试")]
12 | public class TestHangJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestHangJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestHangJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info(nameof(OnStart) + (jobContext.Param ?? string.Empty));
24 |
25 | while (!jobContext.CancelToken.IsCancellationRequested)
26 | {
27 | jobContext.Console.Info("dddd");
28 | await Task.Delay(1000 * 10);
29 | }
30 | jobContext.Console.Warning("game over");
31 | }
32 |
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Test/TestSqlserverHangfireAgent/Jobs/TestJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.Attribute;
7 | using Microsoft.Extensions.Logging;
8 |
9 | namespace TestSqlserverHangfireAgent.Jobs
10 | {
11 | [SingletonJob(RegisterName = "单例job")]//不打这个标签也行 默认就是单例的
12 | public class TestJob : JobAgent
13 | {
14 | private readonly ILogger _logger;
15 |
16 | public TestJob(ILogger logger)
17 | {
18 | _logger = logger;
19 | _logger.LogInformation($"Create {nameof(TestJob)} Instance Success");
20 | }
21 | public override async Task OnStart(JobContext jobContext)
22 | {
23 | jobContext.Console.Info("info消息");
24 | jobContext.Console.Warning("waring消息");
25 | jobContext.Console.Error("error消息");
26 | jobContext.Console.Info("开始等待1秒");
27 | await Task.Delay(1000 * 1);
28 | jobContext.Console.Info("结束等待1秒");
29 | jobContext.Console.WriteLine("开始测试Progressbar", ConsoleFontColor.Cyan);
30 |
31 | var bar = jobContext.Console.WriteProgressBar("testbar");
32 | for (int i = 0; i < 10; i++)
33 | {
34 | bar.SetValue(i * 10);
35 | await Task.Delay(1000);
36 | }
37 | }
38 |
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Test/TestSqlserverHangfireAgent/Jobs/TestTransientJob.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Hangfire.HttpJob.Agent;
7 | using Hangfire.HttpJob.Agent.Attribute;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace TestSqlserverHangfireAgent.Jobs
11 | {
12 | [TransientJob(RegisterName = "多例job")]
13 | public class TestTransientJob:JobAgent
14 | {
15 | private readonly ILogger _logger;
16 |
17 | public TestTransientJob(ILogger logger)
18 | {
19 | _logger = logger;
20 | _logger.LogInformation($"Create {nameof(TestTransientJob)} Instance Success");
21 | }
22 | public override async Task OnStart(JobContext jobContext)
23 | {
24 | jobContext.Console.Warning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
25 | _logger.LogWarning("ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId);
26 | await Task.Delay(5000);
27 | _logger.LogWarning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
28 | jobContext.Console.Warning(nameof(OnStart) + (jobContext.Param ?? string.Empty));
29 | }
30 |
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Test/TestSqlserverHangfireAgent/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Hosting;
10 | using Microsoft.Extensions.Logging;
11 |
12 | namespace TestSqlserverHangfireAgent
13 | {
14 | public class Program
15 | {
16 | public static void Main(string[] args)
17 | {
18 | CreateHostBuilder(args).Build().Run();
19 | }
20 |
21 | public static IHostBuilder CreateHostBuilder(string[] args) =>
22 | Host.CreateDefaultBuilder(args)
23 | .ConfigureWebHostDefaults(webBuilder =>
24 | {
25 | webBuilder.UseStartup()
26 | .ConfigureLogging(logging =>
27 | {
28 | logging.ClearProviders();
29 | #if DEBUG
30 | logging.AddConsole();
31 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
32 |
33 | #else
34 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
35 | #endif
36 | }).UseUrls("http://*:5002");
37 | });
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Test/TestSqlserverHangfireAgent/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:62813",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "TestHangfireAgent": {
19 | "commandName": "Project",
20 | "environmentVariables": {
21 | "ASPNETCORE_ENVIRONMENT": "Development"
22 | },
23 | "applicationUrl": "http://localhost:5000"
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/Test/TestSqlserverHangfireAgent/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Hangfire.HttpJob.Agent;
6 | using Hangfire.HttpJob.Agent.MssqlConsole;
7 | using Microsoft.AspNetCore.Builder;
8 | using Microsoft.AspNetCore.Hosting;
9 | using Microsoft.AspNetCore.Http;
10 | using Microsoft.Extensions.DependencyInjection;
11 | using Microsoft.Extensions.Logging;
12 |
13 | namespace TestSqlserverHangfireAgent
14 | {
15 | public class Startup
16 | {
17 | // This method gets called by the runtime. Use this method to add services to the container.
18 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
19 | public void ConfigureServices(IServiceCollection services)
20 | {
21 | services.AddHangfireJobAgent();
22 | }
23 |
24 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
25 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory logging)
26 | {
27 | app.UseHangfireJobAgent();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Test/TestSqlserverHangfireAgent/TestSqlserverHangfireAgent.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Always
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Test/TestSqlserverHangfireAgent/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Trace",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | },
10 | "JobAgent": {
11 | "Enabled": true,
12 | "SitemapUrl": "/jobagent",
13 | "EnabledBasicAuth": true,
14 | "BasicUserName": "test",
15 | "BasicUserPwd": "123456",
16 | "EnableAutoRegister": true,
17 | "RegisterAgentHost": "http://localhost:5002",
18 | "RegisterHangfireUrl": "http://localhost:5000/job",
19 | "RegisterHangfireBasicName": "admin",
20 | "RegisterHangfireBasicPwd": "test"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/pic1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuzd/Hangfire.HttpJob/34c2888858a3ec239d46726081e8ef936ea11e86/pic1.png
--------------------------------------------------------------------------------
/pic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuzd/Hangfire.HttpJob/34c2888858a3ec239d46726081e8ef936ea11e86/pic2.png
--------------------------------------------------------------------------------
/pic3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuzd/Hangfire.HttpJob/34c2888858a3ec239d46726081e8ef936ea11e86/pic3.png
--------------------------------------------------------------------------------
/pic4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yuzd/Hangfire.HttpJob/34c2888858a3ec239d46726081e8ef936ea11e86/pic4.png
--------------------------------------------------------------------------------