When messages were forwarded they were sent using the low level
connector .send method which accepts a message and sends it over the
link. This method sends the message as is with no modification which
means that at no point during the forwarding logic was the message
sequence number that originated from Link A renumbered to the correct
sequence number to send out on Link B which it was forwarded on.
This in turn caused the logic which drops acked messages from the send
buffer to break which in turn meant the resume could cause duplication
of message and/or messages to be lost. With enough duplicated messages
the resume of one connection could cause other connections to drop and
also initiate resume.
Fix by renumbering the sequence on forwarded messages. In the future
the sequences sent and received should also be checked to make sure this
kind of problem does not happen again, this is not done here because
partially updating a running cluster with sequence problems to one that
checks and enforces sequences numbers will be problematic.
When a plugin broadcasts an event to instances there may be hosts and
instances in the cluster which does not have the plugin loaded. This
would cause an error to be logged for every instance which does not have
the plugin loaded.
Filter out broadcast events sent to hosts and instances such that
instances and hosts that does not have the event do not received them.
When a request is forwarded from a virtual link to a WebSocket link as
is the case when an instance sends a request to the controller the
origin for the request is a virtual link. Handle this case in
_clearPendingRequests instead of throwing an assertion error.
Track the number of requests currently awaiting a response from a
request handler both from interally issued requests and requests
forwarded from other parties.
Add suffixes like Ms and Ns to variables whos time unit is not in
seconds. This is aligning with a new code style of putting units
on variables that are not in SI base units.
Implement remotely initiated stopping and restarting of the controller
and hosts. Restarting is implemented by exiting with a non-zero exit
code and relying on a process manager to start the procress again. To
prevent accidentally trying to restart on a system that doesn't have a
process manager present the --can-restart command line option needs to
be passed to enable the restart operation.
There are more pieces of information about a system than just its CPU,
Memory and disk metrics. To avoid having to build a separate collection
and subscription for metrics and system info, rename the existing system
metrics to system info in anticipation of providing additonal static
system information such as CPU model in it.
Split out host specific data from RegisterHostData that is not related
to the establishment of a connection to the controller into it's own
HostInfoUpdate event. This allows this data to be updated when the
config values they are taken from are changed.
Implement simple collection of basic real time system metrics of hosts
and the controller for the purpose of displaying them in the Web UI. The
metrics are collected by the controller at a configurable interval and
pushed out to web clients currently subscribed to the metrics.
Keep a copy of the instance saves details on the controller so that
saves can be queried even when the host is disconnected and the
controller can properly track and provide updates on the saves to
its clients.
Refactor HostUpdatesEvent, InstanceDetailsUpdatesEvent, ModUpdatesEvent,
ModPackUpdatesEvent and UserUpdatesEvent to have multiple updates of the
entities they support in each event. This is intended to make the events
capable of syncing the entire list that they represent.
Use the JSON data class pattern for User, Role, and PlayerStats and move
them into lib/src/data. This means that User is purely data now and
can't reference role objects directly. To make it possible easily check
permissions attached to roles and store data only visible on the
controller on user objects a ControllerUser type is introduced which is
linked with the UserManager and can therefore reference role objects
directly.
Resolves#525.
Move BaseControllerPlugin to controller/src/BaseControllerPlugin.ts
Move BaseInstancePlugin to host/src/BaseInstancePlugin.ts
Move BaseControlPlugin to ctl/src/BaseCtlPlugin.ts
Move BaseWebPlugin to web_ui/src/BaseWebPlugin.ts
This solves the circular package dependency problem of the base plugins
needing types that are available only in the dependencies to lib.
Be consistent with the usage of tabs as indents in all JSON files in the
project. This makes it easier to configure editors to emit the right
indents when manually editing these files.
When defining a generic type where a type argument is never used
as a part of the type itself, TypeScript will consider two instances of
the generic type with different values for the type to be the same.
This caused the handle method to accept any handler for any
Request/Event, ignoring the event/request type completely.
Fix by specifying the constructor to return the intersection of the type
itself and the Request/Event type.
Remove extra whitespace, use more consistent spacing, add missing
semicolons, using dangling commas, break up long lines, consistent
multiline operator placement, add missing JSDoc strings and so on.
* allow to revoke / restore host access from web ui
* refector to what is expected
* remove core.admin check on HostViewPage.tsx
* update core.host.revoke_token description
* .jsx to .tsx
* controller: tsc --build before webpack-cli
* Type Annotation
* disabled move into the <Input/> and <Checkbox/>
* cleanup debug left over
* documentation
* default ModPack
* modPackUpdateHandlers no undefined
* PluginInfo changes proposition
* PluginInfo changes proposition miss
* ModRecord & ModInfo feedback loop at const mods = [ ?
* ["connect", "drop", "resume", "close"] as const
* .tsx to .ts when possible
Fix updates to Node.js timers types breaking the TypeScript build by
deducing the correct type from the return type of the
setTimeout/setInterval functions.
Messages are forwareded when received from another link, this means it's
too late to throw an error that bubbles up to the code trying to send
the incorrect message thus defeating the purpose of the validation.