- Use http://sweetjs.org/ to implement condition checkers.
Монада maybe на Promise'ах (строчка
return default;
):
newAsyncFunc().then(function(success) {
return anotherAsync();
}, function(error) {
return default;
}).then(function(success) {
return yetAnotherAsync();
}, function(error) {
return default2;
});
-
Bugs: all kinds of invalid implementation. Detected as external contract violation ONLY. All kinds of internal assertion checks ONLY helps to localize a bug. Detection technics:
-
overall integration testing to check contracts
-
runtime checks (???) - localization technique only, we couldn't dynamically predict which result should be (for a RANDOM client request, only CLIENT knows which result is correct - but ever this is not true. We could respond with correctly-looked result, but it could be erroneous - and nobody will know while some output of a subsequent system (or a user) will got outcome). When such bug will be localized and fixed, there will be a regression check (runtime check or in tests only?), could the bug be detected by means of post-assertions?
Runtime check could be implemented in system code after it does its job - right before return result to client. Pre-processing checks are for client contract check (see Valid input below) and invariants (system's internal state and depended systems conditions, i.e., network, HDD/RAM size, CPU load, etc.) System could check available RAM and CPU before function execution if request should be processed quickly. Other ways to guarantee invariants - reserve RAM/CPU/HDD/Network Bandwidth and another resources before processing.
-
-
Invalid input: Intentional or unintentional contract violation from client side. Should be detected by external layer of system's input. Graceful result code handling only - exceptions shouldn't be passed between system and client, because it will be inverted control of client by system. Result code handling should be a part of system's contract - client's failure to specify a valid input should not move system to its contract invalidation.
-
System errors: Contract violations by external executive actors which are NOT PART of the system.
- MUST be handled gracefully
- MUST be retryable
- MUST be passed to client level to control
Contract violations by internal parts of the system (any part, in principle): System could decide to retry with another (not buggy now) part at runtime (but consider to log bug!). Such retry is considered very rare, so... If retry is not possible, the part's violation is violation of the whole's contract - the system contains bugs, and have to report it loudly (fail fast?). In case of such fails, system should switch to fail-safe mode with minimum basic functionality. In principle, production-grade system, when it provided NEW functionality to a client, couldn't switch back to previous version - but client could choose to switch back. If system was worked with user's data (wich HAVE TO be migrated backwards to previous version), it should save user's data as much as possible (but new functionality will be lost!). Described failover switch to previous "stable" version could be used at runtime for a user who triggered some buggy parts. But every another user could too. So, beta-testing could come to continuation of using buggy parts - if it is possible. Downgrade is always a user-choosen step. (In most systems it ever not supported at all). So, if not downgrade, then what? Just store user's data. In new version. Show excuses.
Contract violations by executive actors which are called by system to do its job. Must be handled gracefully in all places. ONE IMPORTANT NOTE ABOUT CONTAINERS AND OWNERSHIP: If executive actors are available to client (semantically known and accessible), system errors handling COULD be raised to client's level by specifying system error condition in system's contract. Otherwise, errors in internal parts of the system which COULD be handled, MUST be handled. BUT: errors are: a) detectable contract violations and b) bugs.
Таким образом, симметричный результат можно привести к вызову любого метода: вызов метода должен подставлять данные, которые идут на вход метода, в реактивную формулу-триггер (вместе с другими данными, группируемыми в формуле по любому критерию, например id сессии/запроса и т.п.). При срабатывании триггера, должен выполняться код обработки (вызов внутреннего, приватного, метода). Без динамического процессинга, любой публичный метод лишь ставит данные на его входе в идентифицируемую транзакцию триггера (присваивает значение внутренней переменной) и вызывает пересчёт реактивной функции. Если результат вычисления положительный, должен выполняться клиентский код, "употребляющий" результат - аггрегат данных транзакции.