Skip to content

Commit

Permalink
[cron] HRInternal-357 initial cron task code (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomasz Opalach committed Dec 17, 2018
1 parent 9e46539 commit ca77617
Show file tree
Hide file tree
Showing 32 changed files with 3,256 additions and 36 deletions.
7 changes: 7 additions & 0 deletions DemoCommon/DemoCommon.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

</Project>
11 changes: 11 additions & 0 deletions DemoCommon/Models/DatabaseSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace DemoCommon.Models
{
public class DatabaseSettings
{
public string[] Urls { get; set; }
public string Name { get; set; }
public string CertificatePath { get; set; }
public string CertificatePassword { get; set; }
public int? RequestsTimeoutInSec { get; set; }
}
}
20 changes: 20 additions & 0 deletions DemoCommon/Models/DemoStats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;

namespace DemoCommon.Models
{
public class DemoStats
{
public const string DocumentId = "DemoStats/1";

public string Id => DocumentId;

public DateTime LastAccessedUtc { get; private set; }

public DemoStats()
{
LastAccessedUtc = DateTime.UtcNow;
}

public void UpdateLastAccess() => LastAccessedUtc = DateTime.UtcNow;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using System;

namespace DemoServer.Utils.Database
namespace DemoCommon.Utils
{
public static class DatabaseName
{
private const string UserDatabasePrefix = "User-";
public const string UserDatabasePrefix = "User-";

public static string For(Guid userId) => $"{UserDatabasePrefix}{userId.ToString()}";
}
Expand Down
22 changes: 22 additions & 0 deletions DemoCron/Arguments/ArgumentsParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.ComponentModel;

namespace DemoCron.Arguments
{
internal class ArgumentsParser
{
private const TaskType DefaultTaskType = TaskType.DeleteUnusedDatabases;

public static TaskType GetTaskType(string[] args)
{
if (args == null || args.Length == 0)
return DefaultTaskType;

if (Enum.TryParse(typeof(TaskType), args[0], out var result))
return (TaskType)result;

throw new InvalidEnumArgumentException(
$"Allowed arguments are: {string.Join(", ", Enum.GetNames(typeof(TaskType)))}");
}
}
}
7 changes: 7 additions & 0 deletions DemoCron/Arguments/TaskType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace DemoCron.Arguments
{
internal enum TaskType
{
DeleteUnusedDatabases
}
}
31 changes: 31 additions & 0 deletions DemoCron/DemoCron.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.3.0" />
<PackageReference Include="RavenDB.Client" Version="4.1.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\DemoCommon\DemoCommon.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
32 changes: 32 additions & 0 deletions DemoCron/DocumentStoreHolder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using DemoCommon.Models;
using Raven.Client.Documents;

namespace DemoCron
{
internal class DocumentStoreHolder
{
private readonly DatabaseSettings _databaseSettings;

private readonly Lazy<IDocumentStore> _lazyStore;

public IDocumentStore Store => _lazyStore.Value;

public DocumentStoreHolder(Settings settings)
{
_databaseSettings = settings.Database;
_lazyStore = new Lazy<IDocumentStore>(CreateStore());
}

private IDocumentStore CreateStore()
{
var store = new DocumentStore
{
Urls = _databaseSettings.Urls,
Database = _databaseSettings.Name
}.Initialize();

return store;
}
}
}
17 changes: 17 additions & 0 deletions DemoCron/Helpers/ConfigExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace DemoCron.Helpers
{
internal static class ConfigExtensions
{
public static TimeSpan ToTimeSpan(this Settings.TimeSpanSettings settings)
{
var days = settings.Days ?? 0;
var hours = settings.Hours ?? 0;
var minutes = settings.Minutes ?? 0;
var seconds = settings.Seconds ?? 0;

return new TimeSpan(days, hours, minutes, seconds);
}
}
}
41 changes: 41 additions & 0 deletions DemoCron/Helpers/PidFileContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Diagnostics;
using System.IO;

namespace DemoCron.Helpers
{
internal class PidFileContext : IDisposable
{
private readonly string _filename;

public PidFileContext(string filename)
{
_filename = filename;
CreatePidFileForCurrentProcess(_filename);
}

public void Dispose()
{
File.Delete(_filename);
}

public void CreatePidFileForCurrentProcess(string filename)
{
if (PidFileHelper.IsTaskRunning(filename, out var pid))
{
throw new InvalidOperationException($"Process is already running (PID {pid}, PID file {filename})");
}

using (var currentProcess = Process.GetCurrentProcess())
{
File.WriteAllText(filename, currentProcess.Id.ToString());
}
}

public static PidFileContext For(Type taskType)
{
return new PidFileContext(PidFileHelper.GetPidFileName(taskType));
}

}
}
44 changes: 44 additions & 0 deletions DemoCron/Helpers/PidFileHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Diagnostics;
using System.IO;

namespace DemoCron.Helpers
{
public class PidFileHelper
{
public static string GetPidFileName(Type taskType)
{
return $"{taskType.Name}.pid";
}

public static bool IsTaskRunning(string pidFilename, out int? processId)
{
if (File.Exists(pidFilename) == false)
{
processId = null;
return false;
}

var pidText = File.ReadAllText(pidFilename)?.Trim();
var pid = int.Parse(pidText);
processId = pid;
try
{
using (var anotherProcess = Process.GetProcessById(pid))
{
return anotherProcess.HasExited == false;
}
}
catch
{
return false;
}
}

public static bool IsTaskRunning(Type taskType)
{
var pidFile = GetPidFileName(taskType);
return IsTaskRunning(pidFile, out var _);
}
}
}
33 changes: 33 additions & 0 deletions DemoCron/Helpers/TaskRunner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Threading.Tasks;
using DemoCron.Arguments;
using DemoCron.Tasks;

namespace DemoCron.Helpers
{
internal static class TaskRunner
{
public static Task Run(TaskType taskType)
{
var type = GetTaskType(taskType);
var pidFilename = PidFileHelper.GetPidFileName(type);
using (var pidFile = new PidFileContext(pidFilename))
{
var task = (CliTask)ServiceLocator.Resolve(type);
return task.Run();
}
}

private static Type GetTaskType(TaskType taskType)
{
switch (taskType)
{
case TaskType.DeleteUnusedDatabases:
return typeof(DeleteUnusedDatabasesTask);

default:
throw new NotSupportedException();
}
}
}
}
40 changes: 40 additions & 0 deletions DemoCron/NLog.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogFile="nlog.log"
>

<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<!-- add your targets here -->

<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.csv">
<layout xsi:type="CsvLayout">
<column name="time"
layout="${time}" />
<column name="logger"
layout="${logger}" />
<column name="threadid"
layout="${threadid}" />
<column name="level"
layout="${level}" />
<column name="message"
layout="${message}" />
<column name="exception"
layout="${exception:format=tostring}" />
</layout>
</target>

<target xsi:type="Console"
name="c"
error="true" />

</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="f" />
<logger name="*" minlevel="Info" writeTo="c" />
</rules>
</nlog>
Loading

0 comments on commit ca77617

Please sign in to comment.