TSCONTSCHEDULEONPOOL(3ts)
π TSContScheduleOnPool β the TSContScheduleOnPool API function, bestie π
okay so this is TSContScheduleOnPool(3ts), from the Apache Traffic Server manual. it's giving "schedule a continuation on a pool of threads" and honestly? she's iconic. let's get into it π¦
β¨ NAME β¨
TSContScheduleOnPool β the TSContScheduleOnPool API function. that's it, that's the name, periodt π
πΈ SYNOPSIS πΈ
#include <ts/ts.h>
TSAction TSContScheduleOnPool(TSCont contp, TSHRTime timeout,
TSThreadPool tp)
look at her. three lil args. so simple. so powerful. π
π DESCRIPTION π
okay so bestie, this is mostly the same as TSContSchedule(). the vibe: it schedules contp on a random thread that belongs to tp. BUT β and this is the lil plot twist β if the thread type of the thread specified by thread affinity is the same as tp, then contp gets scheduled on the thread specified by thread affinity instead. iykyk π«
so basically the continuation is scheduled for a particular thread selected from a group of similar threads, as indicated by tp. and here's the thread pool lineup, no cap:
TS_THREAD_POOL_NETβ Transaction processing threads. Continuations on these threads must not block. like, do not. π«TS_THREAD_POOL_TASKβ Background threads. Continuations can perform blocking operations. live ur truth π«ΆTS_THREAD_POOL_DNSβ DNS request processing. May not exist depending on configuration. Not recommended. πTS_THREAD_POOL_UDPβ UDP processing.
in practice? any choice except TS_THREAD_POOL_NET or TS_THREAD_POOL_TASK is strongly not recommended. fr fr, just don't. π
the TS_THREAD_POOL_NET threads are the same threads on which callback hooks are called, and continuations that use them have the same restrictions. the TS_THREAD_POOL_TASK threads are threads that exist to perform long or blocking actions β although a sufficiently long operation can impact system performance by blocking other continuations on the threads. so like, be mindful. π§
β οΈ Note that theTSContSchedule()family of API shall only be called from an ATSEThread. Calling it from raw non-EThreadscan result in unpredictable behavior. that's the scary kind of unpredictable. π
β οΈ Note that sometimes if theTASKthreads are not ready when you schedule a"contp"on theTS_THREAD_POOL_TASK, then the"contp"could end up being executed in anET_NETthread instead β more likely this is not what you want. π to avoid this you can use theTS_LIFECYCLE_TASK_THREADS_READY_HOOKto make sure that the task threads have been started when you schedule a"contp". you can refer toTSLifecycleHookAdd()for more details. β¨
π EXAMPLE SCENARIOS π
storytime, bestie. four lil scenarios. all of them matter, i'm not skipping a single one. π
π Scenario 1 (no thread affinity info, different types of threads)
when thread affinity is not set, a plugin calls the API on thread "A" (which is an "ET_TASK" type), and wants to schedule on an "ET_NET" type thread provided in "tp" β the system would see there is no thread affinity information stored in "contp." π
in this situation, the system sees there is no thread affinity information stored in "contp". it then checks whether the type of thread "A" is the same as provided in "tp", and sees that "A" is "ET_TASK", but "tp" says "ET_NET". so "contp" gets scheduled on the next available "ET_NET" thread provided by a round robin list, which we will call thread "B". since "contp" doesn't have thread affinity information, thread "B" will be assigned as the affinity thread for it automatically. π―
the reason for doing this is most of the time people want to schedule the same things on the same type of thread, so logically it is better to default the first thread that it is scheduled on as the affinity thread. makes sense, honestly. π
π Scenario 2 (no thread affinity info, same types of threads)
slight variation of scenario 1 β instead of scheduling on an "ET_NET" thread, the plugin wants to schedule on an "ET_TASK" thread (i.e. "tp" contains "ET_TASK" now). all other conditions stay the same. π¦
this time, since the type of the desired thread for scheduling and thread "A" are the same, the system schedules "contp" on thread "A", and assigns thread "A" as the affinity thread for "contp". slay. β¨
the reason behind this choice is that we are trying to keep things simple such that lock contention problems happen less. and for the most part, there is no point of scheduling the same thing on several different threads of the same type, because there is no parallelism between them (a thread will have to wait for the previous thread to finish, either because of locking or because the nature of the job it's handling is serialized since it's on the same continuation). big brain logic, we love to see it. π§
π Scenario 3 (has thread affinity info, different types of threads)
slight variation of scenario 1 β thread affinity is set for continuation "contp" to thread "A", all other conditions stay the same. π
in this situation, the system sees that the "tp" has "ET_NET", but the type of thread "A" is "ET_TASK". so even though "contp" has an affinity thread, the system will not use that information since the type is different β instead it schedules "contp" on the next available "ET_NET" thread provided by a round robin list, which we will call thread "B". the difference with scenario 1 is that since thread "A" is set to be the affinity thread for "contp" already, the system will NOT overwrite that information with thread "B". π¨
most of the time, a continuation will be scheduled on one type of threads, and rarely gets scheduled on a different type. but when that happens, we want it to return to the thread it was previously on, so it won't have any lock contention problems. and that's also why "thread_affinity" is not a hashmap of thread types and thread pointers. π‘
π Scenario 4 (has thread affinity info, same types of threads)
slight variation of scenario 3 β the only difference is "tp" now says "ET_TASK". πΈ
this is the easiest scenario since the type of thread "A" and "tp" are the same, so the system schedules "contp" on thread "A". and, as discussed, there is really no reason why one may want to schedule the same continuation on two different threads of the same type. periodt. π
π NOTE: in scenario 3 & 4, it doesn't matter which thread the plugin is calling the API from. π«Ά
π SEE ALSO π
TSContScheduleTSContScheduleEveryTSContScheduleOnThreadTSLifecycleHookAdd
go read those too bestie, they're the whole friend group π
π COPYRIGHT π
2026, dev@trafficserver.apache.org
and that's the whole page, bestie!! πβ¨ this lil rewrite came to you from Apache Traffic Server, version 9.2, dated Feb 12, 2026 β so if anyone asks, that's the receipts. stay scheduled, stay non-blocking, and please for the love of everything do not call this from a raw non-EThread. mwah ππ¦π
π¦ where this page comes from
- ubuntu questing: trafficserver-dev 9.2.5+ds-1ubuntu2.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms