blob: b3b75421d9af447d55480e7bad45bb0bd1382758 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Mark Slee9f0c6512007-02-28 23:58:26 +000019
Mark Sleef5f2be42006-09-05 21:05:31 +000020#ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_
21#define _THRIFT_CONCURRENCY_THREADMANAGER_H_ 1
Marc Slemko66949872006-07-15 01:52:39 +000022
Marc Slemko0e53ccd2006-07-17 23:51:05 +000023#include <sys/types.h>
Roger Meier4285ba22013-06-10 21:17:23 +020024#include <thrift/concurrency/Thread.h>
James E. King, III82ae9572017-08-05 12:23:54 -040025#include <thrift/stdcxx.h>
Marc Slemko66949872006-07-15 01:52:39 +000026
Konrad Grochowski16a23a62014-11-13 15:33:38 +010027namespace apache {
28namespace thrift {
29namespace concurrency {
Marc Slemko66949872006-07-15 01:52:39 +000030
Mark Sleef5f2be42006-09-05 21:05:31 +000031/**
32 * Thread Pool Manager and related classes
33 *
Mark Sleef5f2be42006-09-05 21:05:31 +000034 * @version $Id:$
35 */
Marc Slemko66949872006-07-15 01:52:39 +000036class ThreadManager;
37
Mark Sleef5f2be42006-09-05 21:05:31 +000038/**
39 * ThreadManager class
40 *
41 * This class manages a pool of threads. It uses a ThreadFactory to create
42 * threads. It never actually creates or destroys worker threads, rather
Jens Geyer1a8e0482015-04-30 20:29:20 +020043 * it maintains statistics on number of idle threads, number of active threads,
Mark Sleef5f2be42006-09-05 21:05:31 +000044 * task backlog, and average wait and service times and informs the PoolPolicy
45 * object bound to instances of this manager of interesting transitions. It is
46 * then up the PoolPolicy object to decide if the thread pool size needs to be
47 * adjusted and call this object addWorker and removeWorker methods to make
48 * changes.
49 *
Jens Geyer1a8e0482015-04-30 20:29:20 +020050 * This design allows different policy implementations to use this code to
Mark Sleef5f2be42006-09-05 21:05:31 +000051 * handle basic worker thread management and worker task execution and focus on
52 * policy issues. The simplest policy, StaticPolicy, does nothing other than
53 * create a fixed number of threads.
54 */
Marc Slemko66949872006-07-15 01:52:39 +000055class ThreadManager {
56
Konrad Grochowski16a23a62014-11-13 15:33:38 +010057protected:
Marc Slemkod466b212006-07-20 00:04:18 +000058 ThreadManager() {}
Marc Slemko66949872006-07-15 01:52:39 +000059
Konrad Grochowski16a23a62014-11-13 15:33:38 +010060public:
James E. King, III82ae9572017-08-05 12:23:54 -040061 typedef apache::thrift::stdcxx::function<void(stdcxx::shared_ptr<Runnable>)> ExpireCallback;
David Reiss068f4162010-03-09 05:19:45 +000062
Marc Slemkod466b212006-07-20 00:04:18 +000063 virtual ~ThreadManager() {}
Marc Slemko66949872006-07-15 01:52:39 +000064
Mark Sleef5f2be42006-09-05 21:05:31 +000065 /**
66 * Starts the thread manager. Verifies all attributes have been properly
67 * initialized, then allocates necessary resources to begin operation
68 */
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000069 virtual void start() = 0;
70
Mark Sleef5f2be42006-09-05 21:05:31 +000071 /**
72 * Stops the thread manager. Aborts all remaining unprocessed task, shuts
James E. King, IIIdf899132016-11-12 15:16:30 -050073 * down all created worker threads, and releases all allocated resources.
Mark Sleef5f2be42006-09-05 21:05:31 +000074 * This method blocks for all worker threads to complete, thus it can
Marc Slemko3a3b53b2007-05-22 23:59:54 +000075 * potentially block forever if a worker thread is running a task that
Mark Sleef5f2be42006-09-05 21:05:31 +000076 * won't terminate.
James E. King, IIIdf899132016-11-12 15:16:30 -050077 *
78 * Worker threads will be joined depending on the threadFactory's detached
79 * disposition.
Mark Sleef5f2be42006-09-05 21:05:31 +000080 */
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000081 virtual void stop() = 0;
82
Konrad Grochowski16a23a62014-11-13 15:33:38 +010083 enum STATE { UNINITIALIZED, STARTING, STARTED, JOINING, STOPPING, STOPPED };
Marc Slemko3a3b53b2007-05-22 23:59:54 +000084
Roger Meier3b771a12010-11-17 22:11:26 +000085 virtual STATE state() const = 0;
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000086
James E. King, IIIdf899132016-11-12 15:16:30 -050087 /**
88 * \returns the current thread factory
89 */
James E. King, III82ae9572017-08-05 12:23:54 -040090 virtual stdcxx::shared_ptr<ThreadFactory> threadFactory() const = 0;
Marc Slemko66949872006-07-15 01:52:39 +000091
James E. King, IIIdf899132016-11-12 15:16:30 -050092 /**
93 * Set the thread factory.
94 * \throws InvalidArgumentException if the new thread factory has a different
95 * detached disposition than the one replacing it
96 */
James E. King, III82ae9572017-08-05 12:23:54 -040097 virtual void threadFactory(stdcxx::shared_ptr<ThreadFactory> value) = 0;
Marc Slemko66949872006-07-15 01:52:39 +000098
James E. King, IIIdf899132016-11-12 15:16:30 -050099 /**
100 * Adds worker thread(s).
101 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100102 virtual void addWorker(size_t value = 1) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000103
James E. King, IIIdf899132016-11-12 15:16:30 -0500104 /**
105 * Removes worker thread(s).
106 * Threads are joined if the thread factory detached disposition allows it.
107 * Blocks until the number of worker threads reaches the new limit.
108 * \param[in] value the number to remove
109 * \throws InvalidArgumentException if the value is greater than the number
110 * of workers
111 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100112 virtual void removeWorker(size_t value = 1) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000113
Mark Sleef5f2be42006-09-05 21:05:31 +0000114 /**
115 * Gets the current number of idle worker threads
116 */
Marc Slemko66949872006-07-15 01:52:39 +0000117 virtual size_t idleWorkerCount() const = 0;
118
Mark Sleef5f2be42006-09-05 21:05:31 +0000119 /**
120 * Gets the current number of total worker threads
121 */
Marc Slemko66949872006-07-15 01:52:39 +0000122 virtual size_t workerCount() const = 0;
123
Mark Sleef5f2be42006-09-05 21:05:31 +0000124 /**
125 * Gets the current number of pending tasks
126 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100127 virtual size_t pendingTaskCount() const = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000128
Mark Sleef5f2be42006-09-05 21:05:31 +0000129 /**
130 * Gets the current number of pending and executing tasks
131 */
Marc Slemko66949872006-07-15 01:52:39 +0000132 virtual size_t totalTaskCount() const = 0;
133
Mark Sleef5f2be42006-09-05 21:05:31 +0000134 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000135 * Gets the maximum pending task count. 0 indicates no maximum
Mark Sleef5f2be42006-09-05 21:05:31 +0000136 */
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000137 virtual size_t pendingTaskCountMax() const = 0;
138
139 /**
James E. King, IIIdf899132016-11-12 15:16:30 -0500140 * Gets the number of tasks which have been expired without being run
141 * since start() was called.
David Reiss068f4162010-03-09 05:19:45 +0000142 */
143 virtual size_t expiredTaskCount() = 0;
144
145 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000146 * Adds a task to be executed at some time in the future by a worker thread.
147 *
148 * This method will block if pendingTaskCountMax() in not zero and pendingTaskCount()
149 * is greater than or equalt to pendingTaskCountMax(). If this method is called in the
150 * context of a ThreadManager worker thread it will throw a
151 * TooManyPendingTasksException
152 *
153 * @param task The task to queue for execution
154 *
155 * @param timeout Time to wait in milliseconds to add a task when a pending-task-count
Aditya Agarwal4b6ff2d2007-12-25 22:58:50 +0000156 * is specified. Specific cases:
157 * timeout = 0 : Wait forever to queue task.
158 * timeout = -1 : Return immediately if pending task count exceeds specified max
David Reiss068f4162010-03-09 05:19:45 +0000159 * @param expiration when nonzero, the number of milliseconds the task is valid
160 * to be run; if exceeded, the task will be dropped off the queue and not run.
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000161 *
162 * @throws TooManyPendingTasksException Pending task count exceeds max pending task count
163 */
James E. King, III82ae9572017-08-05 12:23:54 -0400164 virtual void add(stdcxx::shared_ptr<Runnable> task,
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100165 int64_t timeout = 0LL,
166 int64_t expiration = 0LL) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000167
Mark Sleef5f2be42006-09-05 21:05:31 +0000168 /**
169 * Removes a pending task
170 */
James E. King, III82ae9572017-08-05 12:23:54 -0400171 virtual void remove(stdcxx::shared_ptr<Runnable> task) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000172
David Reiss01fe1532010-03-09 05:19:25 +0000173 /**
174 * Remove the next pending task which would be run.
175 *
176 * @return the task removed.
177 */
James E. King, III82ae9572017-08-05 12:23:54 -0400178 virtual stdcxx::shared_ptr<Runnable> removeNextPending() = 0;
David Reiss01fe1532010-03-09 05:19:25 +0000179
David Reiss068f4162010-03-09 05:19:45 +0000180 /**
181 * Remove tasks from front of task queue that have expired.
182 */
183 virtual void removeExpiredTasks() = 0;
184
185 /**
186 * Set a callback to be called when a task is expired and not run.
187 *
188 * @param expireCallback a function called with the shared_ptr<Runnable> for
189 * the expired task.
190 */
191 virtual void setExpireCallback(ExpireCallback expireCallback) = 0;
192
James E. King, III82ae9572017-08-05 12:23:54 -0400193 static stdcxx::shared_ptr<ThreadManager> newThreadManager();
Marc Slemkod466b212006-07-20 00:04:18 +0000194
Mark Sleef5f2be42006-09-05 21:05:31 +0000195 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000196 * Creates a simple thread manager the uses count number of worker threads and has
197 * a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit
198 * on pending tasks
Mark Sleef5f2be42006-09-05 21:05:31 +0000199 */
James E. King, III82ae9572017-08-05 12:23:54 -0400200 static stdcxx::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count = 4,
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100201 size_t pendingTaskCountMax = 0);
Marc Slemko66949872006-07-15 01:52:39 +0000202
203 class Task;
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000204
Marc Slemko66949872006-07-15 01:52:39 +0000205 class Worker;
206
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000207 class Impl;
Marc Slemko66949872006-07-15 01:52:39 +0000208};
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100209}
210}
211} // apache::thrift::concurrency
Marc Slemko66949872006-07-15 01:52:39 +0000212
Mark Sleef5f2be42006-09-05 21:05:31 +0000213#endif // #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_