Change your Console app’s Main
method to invoke DockerShimRunner.Main
, as such:
using Faithlife.DockerShim;
class Program
{
static void Main(string[] args) => DockerShimRunner.Main(new DockerShimSettings(), context =>
{
Console.WriteLine("Hello World!");
});
}
There are three DockerShim types used in this code:
DockerShimSettings
object with the default settings. These settings control how DockerShim behaves.DockerShimRunner.Main
, passing it the settings object and delegate representing the application logic.DockerShimContext
object with its execution context.DockerShim passes a CancellationToken
to your application logic called DockerShimContext.ExitRequested
. This token is cancelled whenever your application is requested to shut down. When ExitRequested
is cancelled, your application logic should stop taking on new work, finish processing the current work it already has, and then return. If it does not do this, then its processing will be aborted when the application exits.
DockerShim also passes an ILoggerFactory
to your application logic called DockerShimContext.LoggerFactory
, which you can use to construct an ILogger
and log to.
Finally, you should strongly consider setting DockerShimSettings.MaximumRuntime
. Giving this property a reasonable value will ensure your application will exit after a maximum amount of time. If your application is being orchestrated (e.g., in a Kubernetes Deployment), then you can set MaximumRuntime
to create a “phoenix service” - one that periodically exits of its own free will and is then reborn by the orchestrator.
Taking these aspects into account, a more realistic example of DockerShim usage is:
using Faithlife.DockerShim;
class MyProgram
{
private static readonly DockerShimSettings Settings = new DockerShimSettings
{
MaximumRuntime = TimeSpan.FromHours(2),
};
static void Main(string[] args) => DockerShimRunner.Main(Settings, async context =>
{
// Normally loggers are created by dependency injection; this sample just creates it directly.
var logger = context.LoggerFactory.CreateLogger<MyProgram>();
while (true)
{
// Wait for the next work item to be available, and retrieve it.
// If we are requested to exit, then cancel the wait.
var workItem = await GetNextWorkItemAsync(context.ExitRequested);
// Process the work item. Ignore requests to exit.
logger.LogInformation("Processing {workItemId}", workItem.Id);
ProcessWorkItem(workItem);
}
});
}
The actual shutdown time is randomly “fuzzed” a bit by default (see DockerShimSettings.RandomMaximumRuntimeRelativeDelta
). The default value for this is 0.1
(i.e., +/- 10%), so the actual maximum runtime of the code above will vary by +/- 12 minutes (10% of 2 hours), and be a random value between 1:48 and 2:12. This is just to avoid all applications from exiting at the exact same time, even if they were all started at the same time.