skip to Main Content

I have .NET Core 3.1 executable, compiled as framework dependent / portable. I’m running it on a CentOS server, with the .NET Core Runtime installed. The application works completely fine when executed in the terminal, but when I execute from a .service file with systemd, it always “freezes” when executing a http request.

Here’s the .NET code:

//Systemd - Bug hunting
Console.WriteLine("starting download..");
var c = new HttpClient();
var _download = await c.GetStringAsync("https://www.google.com");
Console.WriteLine($"Downloaded {_download.Length} characters.");
//---------------------

Console output when run in the CLI:

starting download..
Downloaded 47466 characters.

As expected..

However, if I run this from a service, the console output (from journalctl) looks like this:

Jan 18 23:34:13 myvps.local mydaemon[1385]: starting download..
Jan 18 23:34:23 myvps.local systemd[1]: mydaemon.service holdoff time over, 
scheduling restart.
Jan 18 23:34:23 myvps.local systemd[1]: Stopped My Daemon Service.
Jan 18 23:34:23 myvps.local systemd[1]: Started My Daemon Service.

And then it starts over again.

It might be worth mentioning that this C# code is executed in a separate thread.

Here’s the service configuration file (/etc/systemd/system/mydaemon.service):

[Unit]
Description=My Daemon Service

[Service]
WorkingDirectory=/home/myuser/applicationDir
ExecStart=/usr/bin/dotnet /home/myuser/applicationDir/mydaemon.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=mydaemon
User=myuser
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

From what I’ve observed, the service somehow isn’t able to send any http requests. I tried this multiple times and I got the same result every time. The dotnet application doesn’t seem to crash, it rather “freezes” and then the restarting timer from the service sets in, causing the application to restart.

How do I need to configure my service for this to work?

2

Answers


  1. Chosen as BEST ANSWER

    I've finally found a solution.

    The problem was that the http request happened in a separate thread, causing systemd to think that the main process has exited. I tried solving this by adding Type=forking to the service configuration file, but with no effect.

    As a workaround, I just added a while loop to the end of the main thread, that logs some info. That way the main process never ends, and thus systemd doesn't fail.

    I know that this is not really the best solution, but it's the only one that worked for me.


  2. Without seeing what the code of the app is doing… if the “another thread” you mention is a Task (it should be, don’t use bare threads) you should Task.WaitAll for all of your other threads/longrunning tasks.

    Main thread should not exit until all of its children are gone.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search