Class ShutdownGate
One signal. ShutdownGate.Signal.enter() is the only question every state-changing path asks: in production it is
PluginInitiationUtils.enterPanelChange(), which is true only while
PluginInitiationUtils.isAcceptingPanelMessages() holds (the accepting flag UltiTools#onDisable clears
as its first step, and Bukkit's isEnabled(), which turns false before onDisable runs). A path
that entered holds a shared permit until ShutdownGate.Signal.exit(); stopAcceptingPanelMessages waits for every
permit to be returned before onDisable goes on, so a change that started before the disable finishes, and
writes its action-log entry, before the action log closes later in onDisable.
Consumers. AgentMessageRouter.dispatch(String, CloudChannel) (every covered type, before the switch
gate and the handler, for the whole handler call) and SerialRequestWorker (the covered file and property
types again when the worker runs them, since a request queued before the disable may run after it). A request that
hands its change to another thread takes a permit of its own for that work and returns it when the work ends, from
whichever thread ends it (22-23 second verification): ModuleRequestHandler for the module responder's
worker, PlayerLinkChannel for the link handler thread. The command handler reads the same flag through
Bindings#disabling on the server thread; work handed to the server thread is not waited for, since it can
only run in a later tick and Bukkit cancels it when UltiTools disables.
Covered types and their refusal (every other request type keeps working until the connection closes):
command.execute,server.power: acknowledged first through the shared ledger (so a redelivery after a restart is acknowledged and never run), thencommand.result/server.power.resultinternal_error;files.write,files.delete,properties.update,config.update,player.action,module.request: their result type withinternal_error;credential.rotate: its acknowledgement has no failure form, so the genericerrorinternal_errorwithreplyTo; the gateway sends the rotation again after the next welcome;player.link.completed: an at-least-once event, not a request. It is left unanswered, so the gateway delivers it again after the next welcome (contract SEMANTICS 19) and the account is provisioned then; a failure receipt would end the delivery with the account not created.
- Since:
- 6.3.1
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static enumHow a refused type is answered.(package private) static interfaceThe one shutdown signal; see the class comment. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final Stringprivate static final Stringprivate final DedupeLedger(package private) static final StringThe message of every refusal.private static final Map<String, ShutdownGate.Refusal> private final ShutdownGate.Signal -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate static voidcover(Map<String, ShutdownGate.Refusal> refusals, Map<String, String> results, String type, ShutdownGate.Refusal refusal, String resultType) (package private) static boolean(package private) booleanenter()(package private) voidexit()(package private) static ShutdownGate.Refusal(package private) voidrefuse(CloudRequest request, CloudChannel channel) Answers a covered request that was not let in.(package private) static StringresultTypeOf(String type)
-
Field Details
-
MESSAGE
The message of every refusal.- See Also:
-
GENERIC_ERROR
- See Also:
-
INTERNAL_ERROR
- See Also:
-
REFUSALS
-
RESULT_TYPES
-
signal
-
ledger
-
-
Constructor Details
-
ShutdownGate
ShutdownGate(ShutdownGate.Signal signal, DedupeLedger ledger) - Parameters:
signal- the shutdown signalledger- the ledger every ack-first request is recorded in, ornullwhen none is bound (an ack-first refusal then sends its acknowledgement without recording the id)
-
-
Method Details
-
coveredTypes
- Returns:
- the state-changing request types this gate covers, in contract order
-
covers
- Parameters:
type- a registered message type- Returns:
- whether the type changes server state and is refused while the server is shutting down
-
refusalOf
- Returns:
- how
typeis answered when refused, ornullwhen it is not covered
-
resultTypeOf
- Returns:
- the type a refusal of
typeis sent as, ornullwhen none is sent
-
enter
boolean enter()- Returns:
- see
ShutdownGate.Signal.enter()
-
exit
void exit()- See Also:
-
refuse
Answers a covered request that was not let in. Never runs the request.- Parameters:
request- the refused requestchannel- the connection it arrived on
-
cover
private static void cover(Map<String, ShutdownGate.Refusal> refusals, Map<String, String> results, String type, ShutdownGate.Refusal refusal, String resultType)
-