Archisteamfarm: IPC server not starting after sending !restart command via IPC

Created on 6 Mar 2018  路  10Comments  路  Source: JustArchiNET/ArchiSteamFarm

Bug

Description

When sending !restart command via IPC, ASF will throw the following exception upon restart:

2018-02-27 18:46:39|ArchiSteamFarm-10077|ERROR|ASF|Start() System.Net.HttpListenerException (0x80004005): Address already in use
at System.Net.HttpEndPointManager.GetEPListener(String host, Int32 port, HttpListener listener, Boolean secure)
at System.Net.HttpEndPointManager.AddPrefixInternal(String p, HttpListener listener)
at System.Net.HttpEndPointManager.AddListener(HttpListener listener)
at System.Net.HttpListener.Start()
at ArchiSteamFarm.IPC.Start(HashSet`1 prefixes)

Additional info

I am running ASF on a raspberry pi. This bug will not occur on windows.

Can't reproduce Not a bug Won't fix

Most helpful comment

Um yeah, this has happened countless times to me on *nix as well, but it's a dotnet bug...

dotnet/corefx/issues/25016

And there's probably a workaround?

https://github.com/dotnet/corefx/issues/24562#issuecomment-335670598

Edit: Nevermind

All 10 comments

repro

Um yeah, this has happened countless times to me on *nix as well, but it's a dotnet bug...

dotnet/corefx/issues/25016

And there's probably a workaround?

https://github.com/dotnet/corefx/issues/24562#issuecomment-335670598

Edit: Nevermind

It doesn't happen every time @JustArchi but it does happen, I've had it happen both with doing both !restart and during a update sequence as well.

Doesn't matter to me, ASF properly stops HttpListener prior to restarting with !restart command, and ensures it's stopped before it spawns new restarted process in the first place. There is nothing in ASF code to improve regarding this, because HttpListener is already not listening before we even attempt to move forward. Whether underlying socket is freed or not, that's up to .NET Core runtime, not ASF.

Instead, it should be properly fixed with https://github.com/dotnet/corefx/pull/24809

Looks like it's ASF, not .NET Core, since the bug doesn't pop out when using "!restart" command via Steam chat. But it is while auto-update or using IPC command.

Program shutdown routine is exactly the same regardless whether program exits or restarts, and regardless whether you use a command, get done with auto-update or click [X] button. The underlying issue is sockets not being freed, not ASF not releasing them.

Looked at the code a bit, many async methods, they are not the same every call time, path/conditions count. Had you experimented with just inserting big enough Task.Delay before the Process.Start in Program.Restart? (Just dirty hack to prove the problem.)

_(But since not bug reports from Windows - my case is Linux - it depends on .NET Core platform too.)_

If you start reading ASF code, at least do it properly. This function executes before exit and restart, and ASF already stops IPC entirely prior to even calling Process.Start() in the first place. If you think you know better, feel free to fix ASF and send appropriate PR that I'll evaluate. Or consider the fact that ASF has no outcome on third-party runtime bugs and it's better to wait for fix in .NET Core 2.1 rather than wasting your time for something that will get obsolete in 3 days from now. Up to you of course, just don't expect me to do the second myself.

  • This is ASF bug, because: a) application should not continue run if configured behaviour can't be reached and b) unhandled exception is bug, even if it's ignored and logged. Application either can workaround platform bugs, or be as buggy as platform. "Not my job", old as a world, no surprise if .NET Core dev which planted the bug use it also.
  • About proper code reading. I've did it properly enough, but it doesn't mean I could read all the ASF code, especially if I see ASF's code (and C# .NET Core code as well) the first time in my life.
  • About my expectations. I don't expect anything, even my post are read. I can easily workaround the problem by disabling restart and adding wrapper script.
  • On how to fix ASF. Your answer to my question, translated, is "No need, app should be shutdown completely to initiate HttpListener correct dispose." I would not have dared to tell you how to drive your project. What I do if I would run the show, knowing about such platform bugs which aren't fixed for months (with possible delays and possible regressions are coming), is just to cycle this code from IPC.Start with delays several times in case of catch and exited with unrepairable error if it didn't help (about 5 lines of code should be added):
            HttpListener = new HttpListener { IgnoreWriteExceptions = true };

            try {
                foreach (string prefix in prefixes) {
                    ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.IPCStarting, prefix));
                    HttpListener.Prefixes.Add(prefix);
                }

                HttpListener.Start();
            } catch (Exception e) {
                // HttpListener can dispose itself on error, so don't keep it around
                HttpListener = null;
                ASF.ArchiLogger.LogGenericException(e);
            }
  • Why I won't do it by myself. It will take several hours to get into the development of .NET Core, write the code and test it before sending pull, but I would surely spend them if I believe that my participation is welcome. But from the tone of our conversation I see that it's not. I am sorry in case I've told something offensive or made other provocative actions. I'm sorry about all posts I've wrote here, that won't happen again.

I'm not entirely sure if you're doing it on purpose or you don't understand at all what I'm saying.

This is ASF bug

This is .NET Core bug that ASF is running into. ASF bug implies that the bug should be fixed inside ASF, while this bug should not be fixed inside ASF. This bug should be fixed in the runtime. Whether ASF should work it around or not is entirely different matter.

a) application should not continue run if configured behaviour can't be reached

Application should always attempt to recover from errors, unless they're severe enough to justify termination. Your issue is not.

b) unhandled exception is bug, even if it's ignored and logged.

Unhandled exception causes ASF to terminate instantly, your issue is not unhandled exception.

"Not my job", old as a world

Do you even realize what you're saying or you're using random sentences without any context? I said that I'm not going to work it around because it's already reported, already acknowledged and already fixed in appropriate place. Do you realize that? Do you realize that it doesn't make any freaking sense to workaround a bug that won't exist in a week from now? Do you realize that what you're suggesting makes no freaking sense from any coding standpoint and you're talking without any point? Or maybe you want to argue that I'm refusing to fix a bug that doesn't exist anymore?

About proper code reading. I've did it properly enough, but it doesn't mean I could read all the ASF code, especially if I see ASF's code (and C# .NET Core code as well) the first time in my life.

Then perhaps you should make less assumptions and ask more questions, because you've assumed that ASF does not stop listener at all and you know better what it should do, which is wrong. You didn't analyze the code, you've noticed bunch of asynchronous functions without even checking how they're called, what is the general flow and what is the cause of your issue. In other words, "I know nothing but I'll tell you what you should do".

Why I won't do it by myself. It will take several hours to get into the development of .NET Core, write the code and test it before sending pull

It'd take you several days only to confirm that everything you've said until now doesn't make any sense. Runtime bugs should be fixed in the runtime, not in the ASF. Your solution wouldn't work because of TCP fin timeout on Linux that holds socket in TIME_WAIT state that you didn't even think of being possible, since you're so centered about what you think is right that you don't even understand where the root cause in fact is. You don't realize that on Linux incorrectly set socket will stay in this state for whole 60 seconds after process exit, and you don't understand how ASF waiting those 60 seconds and retrying to raise IPC interface is wrong, because it should not be happening in the first place. You also don't understand how the workaround should be done only where absolutely necessary, e.g. where I can't fix the runtime myself - this case does not apply here.

I swear this is the last time I'm wasting my time trying to explain things when I should simply comment with "No, you're wrong".

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JustArchi picture JustArchi  路  4Comments

KazeZlat picture KazeZlat  路  4Comments

Botan626 picture Botan626  路  4Comments

tambry picture tambry  路  4Comments

undefo picture undefo  路  4Comments