Add support for multiple rooms per process #25
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds opt-in support for multiple rooms per process by leveraging Unreal's forking capabilities to fork a parent process into multiple children processes.
Briefly, to enable support, users need to:
ENTRYPOINT
lines inDockerfile
For convenience, here are the contents of the included
SDKDemo/Plugins/HathoraSDK/Source/HathoraSDK/Public/Forking/README.md
:Hathora Forking / Multiple Rooms Per Process
This is an overview of what these additional classes provide and how to use them.
Overview
To enable more than 1 room per "Hathora Process" (aka Number of rooms per process > 1) within Unreal, we need to accomplish these tasks:
Epic Games has documented about supporting this in this article. This article provides the
FForkProcess.h
that is mentioned in a more broad article about hosting advice they did.This class provides a helper function to wrap around the UE built-in mechanisms for forking.
Note that forking is only supported for Linux Dedicated Servers (as
FUnixPlatformProcess
is the only platform that implements theWaitAndFork()
method).Forking in Unreal
From a birds-eye view, here is roughly how forking is implemented in these classes.
UHathoraForkingSubsystem::Fork
callsFHathoraForkProcess::ForkIfRequested
.FHathoraForkProcess
is the same as the providedFForkProcess
from the forementioned article. We renamed it to not conflict if you copy it separately. This class helps with forking, but Epic never published it as part of Unreal.FHathoraForkProcess::ForkIfRequested
callsFPlatformProcess::WaitAndFork
, which if you're using Linux callsFUnixPlatformProcess::WaitAndFork
FUnixPlatformProcess::WaitAndFork
calls the system callfork()
for the-NumForks
command line parameter (which we automatically inject into the command line inUHathoraForkingSubsystem
to equal the environment variableHATHORA_ROOMS_PER_PROCESS
injected by Hathora).-NumForks
times, it will then continue to monitor and wait for children processes to terminate. If they do terminate with anything other than a special exit code, it will fork for them again.-WaitAndForkCmdLinePath
command line parameter (also automatically injected byUHathoraForkingSubsystem
). There needs to be a file for each child process in this folder with the name equal to the index of the child (1-based, e.g. "1", "2", "3", etc.). This is a text file with the command line parameters (e.g.-port=7778
).UHathoraForkingSubsystem
by using an incrementing port for each child (e.g. 7777, 7778, 7779). If you specify-port
on the master process command line or config file, that will be the base which the system will increment on.UHathoraForkingSubsystem
where there is some subsequent Hathora Cloud API calls before continuing the server tickingTo use Unreal's forking system, you must specify
-nothreading
on the command line of the parent/master process. We cannot automatically inject this command line parameter, so you must manually modify your call (e.g. your entrypoint in yourDockerfile
) to add this. This is just a hard requirement by the engine code; without it it will just not fork.To use the provided
UHathoraForkingSubsystem
, you also need to specify-PostForkThreading
command line parameter for the parent/master process to ensure the HTTP calls can happen on a separate thread.We've provided an example of this in the
Dockerfile
at the root of the Hathora SDK demo repo.UHathoraForkingSubsystem
The provided
UHathoraForkingSubsystem
class provides a full example of how to implement the full life cycle. You may need to modify this depending on any third-party vendors.This is a singleton class that will initialize during engine startup. See the Unreal documentation on Subsystems for more details there.
UHathoraForkingSubsystem
is aUGameInstanceSubsystem
to ensure it loads when theUGameInstance
loads.UHathoraForkingSubsystem
provides a publicvoid Fork()
function that will start the forking process. This is a blocking function and should be called when you want to separate the parent and child processes. By default,UHathoraForkingSubsystem
calls this in itsInitialize()
function if the project setting is enabled.This
Fork()
method will do the following:GetProcessInfo
Hathora Cloud API call), saving them for children processes to use-port=XXXX
and-PostForkThreading
(note, that you still have to specify this in your startup command for the parent process; we inject it here too for the children process as the flag is used both by the parent and children processes).FHathoraForkProcess::ForkIfRequested
as mentioned aboveGetActiveRoomsForProcess
API call until there is a room they can self-assignhathoraGamePort
variable which is the public/exposed port for that child process/roomUHathoraLobbyComponent
has logic in it to extract this variable if the project setting is enabled for the client and use that port instead of the defaultexposedPort.port
variable from theGetConnectionInfo
API call.Enabling via Project Settings
This functionality is disabled by default and must be enabled in your Project Settings. Under
Plugins > Hathora SDK
, enableUse Built In Forking
to enable processing supporting forking functionality. You may need to click theSet as Default
button to save the setting to theConfig/DefaultGame.ini
config file for it to be properly packaged in.More Technical Details
The HathoraForkingSubsystem.cpp source file has more comments on described behavior of how this all functions.