xf 5 mesiacov pred
rodič
commit
e1607d7241

+ 1 - 1
build/Dockerfile

@@ -1,4 +1,4 @@
 FROM  mcr.microsoft.com/dotnet/aspnet:8.0
 WORKDIR /app
 COPY out/ .
-ENTRYPOINT ["dotnet", "Hotline.Api.dll"]
+ENTRYPOINT ["dotnet", "Scheduler.dll"]

+ 0 - 33
build/docker-compose.yml

@@ -1,33 +0,0 @@
-version: '3.4'
-
-services:
-  hotline:
-    image: ${DOCKER_REGISTRY-fw}/hotline:${TAG:-latest}
-    container_name: hotline
-    environment:
-      - "TZ=Asia/Shanghai"
-    #restart: on-failure
-    ports:
-      - "50100:80"
-      - "50103:50001"
-
-  hotline-dapr:
-    image: "daprio/daprd:edge"
-    command: [ "./daprd", 
-    "-app-id", "hotline", 
-    "-app-port", "80",
-    "-dapr-http-port", "50105",
-    #"-components-path", "/components",
-    #"-config", "/configuration/config.yaml"
-    ]
-    #volumes:
-    #- "./dapr/components/:/components"
-    #- "./dapr/configuration/:/configuration"
-    depends_on:
-      - hotline
-    network_mode: "service:hotline"
-
-networks:
-  default:
-    external: true
-    name: fw-dapr-network

+ 40 - 0
src/Scheduler/Program.cs

@@ -1,4 +1,7 @@
+using Quartz;
+using Quartz.AspNetCore;
 using Scheduler.Components;
+using Scheduler.ScheduleModule;
 
 var builder = WebApplication.CreateBuilder(args);
 
@@ -7,6 +10,43 @@ builder.Services.AddRazorComponents()
     .AddInteractiveServerComponents()
     .AddInteractiveWebAssemblyComponents();
 
+var services = builder.Services;
+services.AddHttpClient();
+services.AddSingleton<BaseHttpRequestJob>();
+
+var jobs = builder.Configuration.GetSection("Jobs")?.Get<List<AppJob>>()?
+    .Where(d => d.Enable && !string.IsNullOrEmpty(d.Cron))
+    .ToList();
+if (jobs != null && jobs.Any())
+{
+    builder.Services.AddQuartz(d =>
+    {
+        d.SchedulerId = "default_scheduler";
+        d.InterruptJobsOnShutdown = true;
+        d.InterruptJobsOnShutdownWithWait = true;
+        d.MaxBatchSize = 3;
+
+        d.AddJob<BaseHttpRequestJob>(BaseHttpRequestJob.Key);
+        foreach (var job in jobs)
+        {
+            d.AddTrigger(t => t
+                .UsingJobData("job", System.Text.Json.JsonSerializer.Serialize(job))
+                .ForJob(BaseHttpRequestJob.Key)
+                .StartNow()
+                .WithCronSchedule(job.Cron));
+        }
+    });
+
+    builder.Services.AddQuartzServer(d =>
+    {
+        d.WaitForJobsToComplete = true;
+        d.StartDelay = TimeSpan.FromSeconds(5);
+    });
+
+}
+
+
+
 var app = builder.Build();
 
 // Configure the HTTP request pipeline.

+ 29 - 0
src/Scheduler/ScheduleModule/AppJob.cs

@@ -0,0 +1,29 @@
+using HttpMethod = Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod;
+
+namespace Scheduler.ScheduleModule
+{
+    public class AppJob
+    {
+        public string Id { get; set; }
+        public string Name { get; set; }
+        public string? Description { get; set; }
+        public string Cron { get; set; }
+        public bool Enable { get; set; }
+        public EJobType JobType { get; set; }
+
+        public HttpMethod Method { get; set; }
+
+        public string Path { get; set; }
+        //todo header, params
+    }
+
+    public enum EJobType
+    {
+        HttpRequest = 0,
+
+        /// <summary>
+        /// 内部执行任务
+        /// </summary>
+        InnerTask = 1,
+    }
+}

+ 36 - 0
src/Scheduler/ScheduleModule/BaseHttpRequestJob.cs

@@ -0,0 +1,36 @@
+using Quartz;
+using System.Net.Http.Json;
+using Console = System.Console;
+
+namespace Scheduler.ScheduleModule
+{
+    public class BaseHttpRequestJob : IJob, IDisposable
+    {
+        private readonly IHttpClientFactory _clientFactory;
+
+        public BaseHttpRequestJob(IHttpClientFactory clientFactory)
+        {
+            _clientFactory = clientFactory;
+        }
+
+        public static readonly JobKey Key = new JobKey(nameof(BaseHttpRequestJob), "group of HttpRequestJob");
+
+        public async Task Execute(IJobExecutionContext context)
+        {
+            var reqString = context.MergedJobDataMap.GetString("job");
+            if (reqString == null) return;
+            var job = System.Text.Json.JsonSerializer.Deserialize<AppJob>(reqString);
+            if (job == null) return;
+            Console.WriteLine($"{job.Id}, {job.Name}");
+
+            var httpClient = _clientFactory.CreateClient();
+            await httpClient.PostAsync(job.Path, null, context.CancellationToken);
+        }
+
+        /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+        public void Dispose()
+        {
+            
+        }
+    }
+}

+ 2 - 0
src/Scheduler/Scheduler.csproj

@@ -8,6 +8,8 @@
 
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.4" />
+    <PackageReference Include="Quartz.AspNetCore" Version="3.13.1" />
+    <PackageReference Include="Quartz.Jobs" Version="3.13.1" />
   </ItemGroup>
 
   <ItemGroup>

+ 23 - 1
src/Scheduler/appsettings.json

@@ -5,5 +5,27 @@
       "Microsoft.AspNetCore": "Warning"
     }
   },
-  "AllowedHosts": "*"
+  "AllowedHosts": "*",
+  "Jobs": [
+    {
+      "Id": "111",
+      "Name": "test0",
+      "Description": "",
+      "Cron": "0/1 * * * * ?",
+      "Enable": true,
+      "JobType": 0,
+      "Method": 3, //get:0, post:3
+      "Path": ""
+    },
+    {
+      "Id": "222",
+      "Name": "test1",
+      "Description": "",
+      "Cron": "0/5 * * * * ?",
+      "Enable": true,
+      "JobType": 0,
+      "Method": 3, //get:0, post:3
+      "Path": ""
+    }
+  ],
 }