| 68 | } |
| 69 | |
| 70 | static int |
| 71 | txn_queue_cont(TSCont cont, TSEvent /* event ATS_UNUSED */, void * /* edata ATS_UNUSED */) |
| 72 | { |
| 73 | auto *limiter = static_cast<TxnRateLimiter *>(TSContDataGet(cont)); |
| 74 | QueueTime now = std::chrono::system_clock::now(); // Only do this once per "loop" |
| 75 | |
| 76 | // Try to enable some queued txns (if any) if there are slots available |
| 77 | while (limiter->size() > 0 && limiter->reserve() != ReserveStatus::FULL) { // Can't be UNLIMITED here |
| 78 | auto [txnp, contp, start_time] = limiter->pop(); |
| 79 | std::chrono::milliseconds delay = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time); |
| 80 | |
| 81 | delayHeader(txnp, limiter->header(), delay); |
| 82 | Dbg(dbg_ctl, "Enabling queued txn after %ldms", static_cast<long>(delay.count())); |
| 83 | // Since this was a delayed transaction, we need to add the TXN_CLOSE hook to free the slot when done |
| 84 | TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, contp); |
| 85 | limiter->incrementMetric(RATE_LIMITER_METRIC_RESUMED); |
| 86 | TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); |
| 87 | } |
| 88 | |
| 89 | // Kill any queued txns if they are too old |
| 90 | if (limiter->size() > 0 && limiter->max_age() > std::chrono::milliseconds::zero()) { |
| 91 | now = std::chrono::system_clock::now(); // Update the "now", for some extra accuracy |
| 92 | |
| 93 | while (limiter->size() > 0 && limiter->hasOldEntity(now)) { |
| 94 | // The oldest object on the queue is too old on the queue, so "kill" it. |
| 95 | auto [txnp, contp, start_time] = limiter->pop(); |
| 96 | std::chrono::milliseconds age = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time); |
| 97 | |
| 98 | delayHeader(txnp, limiter->header(), age); |
| 99 | Dbg(dbg_ctl, "Queued TXN is too old (%ldms), erroring out", static_cast<long>(age.count())); |
| 100 | TSHttpTxnStatusSet(txnp, static_cast<TSHttpStatus>(limiter->error())); |
| 101 | TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp); |
| 102 | limiter->incrementMetric(RATE_LIMITER_METRIC_EXPIRED); |
| 103 | TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR); |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | return TS_EVENT_NONE; |
| 108 | } |
| 109 | |
| 110 | /////////////////////////////////////////////////////////////////////////////// |
| 111 | // Parse the configurations for the TXN limiter. |
nothing calls this directly
no test coverage detected