C
C#16mo ago
khamas

❔ how do delay the process exit for a graceful shutdown in a console app?

Hey, I want to delay the app exit by a few seconds, I tried using the following but it's just exiting instantaneously
AppDomain.CurrentDomain.ProcessExit += delegate(object sender, EventArgs eventArgs)
{
GlobalState.CancellationRequested = true;
LogService.EzLogger.LogInfoAsync("[PROCESSOR] Shutting down gracefully", null);
Console.WriteLine("Shutting down...");
Thread.Sleep(TimeSpan.FromSeconds(30));
Console.WriteLine("Finished shutting down...");
};
AppDomain.CurrentDomain.ProcessExit += delegate(object sender, EventArgs eventArgs)
{
GlobalState.CancellationRequested = true;
LogService.EzLogger.LogInfoAsync("[PROCESSOR] Shutting down gracefully", null);
Console.WriteLine("Shutting down...");
Thread.Sleep(TimeSpan.FromSeconds(30));
Console.WriteLine("Finished shutting down...");
};
31 Replies
IsNotNull
IsNotNull16mo ago
If I had to have something safe exit, I'd run it in an OS service. We had to try and capture exit from a UI app once (to avoid corrupting a QuickBooks file we were connected to), and it was a pain that almost never worked. You'd still have to deal with OS crashes and hard drive failures anyways.
khamas
khamasOP16mo ago
I do but I want to just stop some background workers it's better if it's graciously exiting but it will handle crashes
IsNotNull
IsNotNull16mo ago
Your process is in a service, and you need to stop other background workers. Are the background workers running in the same process? Are they ones you started yourself as part of the service? @IUndisposable<Fleksi>
khamas
khamasOP16mo ago
it's a console app that starts while(true) tasks I stop them via a global bool this allows me to control exactly when I can stop "safely" in the task
IsNotNull
IsNotNull16mo ago
Why not just pass them a CancellationToken when they start?
khamas
khamasOP16mo ago
I could but that's not the issue
IsNotNull
IsNotNull16mo ago
Signalling that the subtasks have finished is your issue?
khamas
khamasOP16mo ago
I want to delay the exit of my process, token or bool doesn't matter signaling works fine it's the process that exits too quickly
IsNotNull
IsNotNull16mo ago
When I've used windows services (using the service worker dotnet new template) it has a shutdown method...I was under the impression the OS will wait for services to shutdown a certain amount of time before they force them closed? Is that not the case?
khamas
khamasOP16mo ago
yeah but this is a console app and the event handler is supposed to do that
IsNotNull
IsNotNull16mo ago
Ah, its not a service
khamas
khamasOP16mo ago
but it seems to not wait even if I ask it to
IsNotNull
IsNotNull16mo ago
I remember with the app I mentioned earlier that we had to try two or three different approaches before we found one that would 'usually' work
khamas
khamasOP16mo ago
ok so I just did some debugging
IsNotNull
IsNotNull16mo ago
I think we were calling into a win32 api. Not sure that would help you much if you are looking for a cross platform approach
khamas
khamasOP16mo ago
it seems to wait 10 seconds now so now I gotta configure docker to wait for longer
IsNotNull
IsNotNull16mo ago
I think the issue we ran into was that the process was getting killed when the terminal window was being closed, so it still wasn't 'shutting down'
khamas
khamasOP16mo ago
well I used ctrl+c idk
IsNotNull
IsNotNull16mo ago
Like, ctrl-c was fine, but 'x' on the terminal still broke it Is this for your db project?
khamas
khamasOP16mo ago
no we are switching over to kubernetes at work so I need to implement some safe exits since kube randomly kills off processes also the db is C++ 😛 anyways thanks
IsNotNull
IsNotNull16mo ago
I remembered that, but I wasn't sure if you had a C# host process. Figured I'd ask, since unexpected db shutdown is a pretty sensitive topic and I'm curious how people deal with it
khamas
khamasOP16mo ago
well usually you will have a commit log that holds the data as a copy and you have a bunch of flags in your binary document file basically you would have a flag telling that the document is no corrupted when editing the data you copy data to the commit log, then unset the corrupt flag while editing the data once done, you but the flag back and delete the log then it's all upto the parser to check the log if the document is corrupted and get the data from the log itself this does however slow down the process by quite a a bit so you'd usually have a few background threads doing that work in chunks
IsNotNull
IsNotNull16mo ago
You are reminding me why I liked working on an append only database with row-by-row records. I just throw out any incomplete rows harold
khamas
khamasOP16mo ago
haha also my db will feature a "return uncommitted" insert so you can basically insert data as a fire and forget useful for storing non-crucial data, such as system logs among others because when inserting, you are not directly inserting on the data set, you are appending to a log then a worker moves the log data to the actual set it's not very complicated, just tedious to implement
IsNotNull
IsNotNull16mo ago
Is there a limit to how often it flushes to disk when writing to the log file? Or is that more of a writethrough operation?
khamas
khamasOP16mo ago
it will use a thread safe channel so the worker will get fed some data, then commit the log
IsNotNull
IsNotNull16mo ago
I was referring to file system caching. The data isn't actually on disk until its flushed, right?
khamas
khamasOP16mo ago
also to save resources I'll try to add a query thread "piggyback" feature so when a thread is already reading from a table, it can hot-link a new query then execute both queries on the same thread so like if thread T1 is reading rows 10M-50M for query Q1, query Q2 can delegate a part of the query to T1, then thread T2 could read 0-10M(+ offset from T1) rows
IsNotNull
IsNotNull16mo ago
That only works if they have aren't using transactions with isolation?
khamas
khamasOP16mo ago
well T1 can always access the transaction context if it deems the work to be too much, it will unclaim the query then T2 will resume where it left off this relies on a ton of shared state so thread safety is paramount I plan on using a lot of reader-writer locks I might need to create my own "role-based" lock
Accord
Accord16mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server