Subj – how could I allowdisallow actions in my system based on the state of another external system (I have access to it’s state via the shared DB table)? I can get the state of another system almost immediately, another system is like a state machine with some states like ‘running’, ‘maintenance’, ‘initializing’ etc.

For example there are some of my commands and queries

  1. DeleteExternalSystem(systemId)
  2. ChangeStateOfExternalSystem(newState)
  3. DoSomethingWithExternalSystem1(systemId, param)
  4. DoSomethingWithExternalSystem2(systemId, param)

If external system is in state ‘initializing’ I want to prohibit calling of DeleteExternalSystem and ChangeStateOfExternalSystem, but allow to call DoSomethingWithExternalSystem1 and like so many other cases. Some of them should also return OK status for some specific states without actually executing underlying method. Also important point – state of external system could be changed inside my commands sometimes. For example command could switch system from the state ‘maintenance’ to state ‘running’ and so on.

Could someone suggest me the preffered approach to this problem? Maybe there are some patterns which could be used to bypass my problem?


Prohibit calling how?

If we were talking about some GUI you could mean graying out buttons until the state they require is reached. But now you have to constantly poll the other system state to keep the enabled/disabled state of your buttons current. If that’s what you do you’ll want to see if you can pack all the states you care about into one simple message to minimize the traffic this will cause. But even that will occasionally allow button presses at the wrong time.

If we’re talking about commands a user can just type at a command line then you really can’t disable them.

What you can do is remember these are commands. Not guarantees.

No command ever designed ensures obedience. How obedience, or lack thereof, is communicated varies wildly. But obedience is a result. Not something you predict. Even if you poll every millisecond a button could be clicked just as the ‘initializing’ state starts. The important thing isn’t to forbid the call. It’s to ensure the call can be rejected without causing harm.

If you must ensure multiple states (both not initializing and systemId deleted) you may want to consider a transaction. These can roll back their changes when the requirements fail.

If going that far is really needed depends on how the external system reacts to a delete command while initializing. Does it give an error message or does it enter an invalid state?

If it enters an invalid state it needs fixing. If that’s not an option try transactions. But polling it’s state to learn when it’s OK to delete is just setting you up for a race condition. Best you’re doing is lowering the odds that something nasty happens. Not really fixing it. It’s the classic mistake of checking if a file exists before writing to it and assuming it still exists between your check and your write. You don’t really know.


Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *