blob: d8bf71b8d5829185bd62891c4794522e6bd1e37c [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 Slemko6f038a72006-08-03 18:58:09 +000023#include <boost/shared_ptr.hpp>
Roger Meier82525772012-11-16 00:38:27 +000024#include <thrift/cxxfunctional.h>
Marc Slemko0e53ccd2006-07-17 23:51:05 +000025#include <sys/types.h>
Roger Meier4285ba22013-06-10 21:17:23 +020026#include <thrift/concurrency/Thread.h>
Marc Slemko66949872006-07-15 01:52:39 +000027
Konrad Grochowski16a23a62014-11-13 15:33:38 +010028namespace apache {
29namespace thrift {
30namespace concurrency {
Marc Slemko66949872006-07-15 01:52:39 +000031
Mark Sleef5f2be42006-09-05 21:05:31 +000032/**
33 * Thread Pool Manager and related classes
34 *
Mark Sleef5f2be42006-09-05 21:05:31 +000035 * @version $Id:$
36 */
Marc Slemko66949872006-07-15 01:52:39 +000037class ThreadManager;
38
Mark Sleef5f2be42006-09-05 21:05:31 +000039/**
40 * ThreadManager class
41 *
42 * This class manages a pool of threads. It uses a ThreadFactory to create
43 * threads. It never actually creates or destroys worker threads, rather
Jens Geyer1a8e0482015-04-30 20:29:20 +020044 * it maintains statistics on number of idle threads, number of active threads,
Mark Sleef5f2be42006-09-05 21:05:31 +000045 * task backlog, and average wait and service times and informs the PoolPolicy
46 * object bound to instances of this manager of interesting transitions. It is
47 * then up the PoolPolicy object to decide if the thread pool size needs to be
48 * adjusted and call this object addWorker and removeWorker methods to make
49 * changes.
50 *
Jens Geyer1a8e0482015-04-30 20:29:20 +020051 * This design allows different policy implementations to use this code to
Mark Sleef5f2be42006-09-05 21:05:31 +000052 * handle basic worker thread management and worker task execution and focus on
53 * policy issues. The simplest policy, StaticPolicy, does nothing other than
54 * create a fixed number of threads.
55 */
Marc Slemko66949872006-07-15 01:52:39 +000056class ThreadManager {
57
Konrad Grochowski16a23a62014-11-13 15:33:38 +010058protected:
Marc Slemkod466b212006-07-20 00:04:18 +000059 ThreadManager() {}
Marc Slemko66949872006-07-15 01:52:39 +000060
Konrad Grochowski16a23a62014-11-13 15:33:38 +010061public:
Roger Meier82525772012-11-16 00:38:27 +000062 typedef apache::thrift::stdcxx::function<void(boost::shared_ptr<Runnable>)> ExpireCallback;
David Reiss068f4162010-03-09 05:19:45 +000063
Marc Slemkod466b212006-07-20 00:04:18 +000064 virtual ~ThreadManager() {}
Marc Slemko66949872006-07-15 01:52:39 +000065
Mark Sleef5f2be42006-09-05 21:05:31 +000066 /**
67 * Starts the thread manager. Verifies all attributes have been properly
68 * initialized, then allocates necessary resources to begin operation
69 */
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000070 virtual void start() = 0;
71
Mark Sleef5f2be42006-09-05 21:05:31 +000072 /**
73 * Stops the thread manager. Aborts all remaining unprocessed task, shuts
James E. King, IIIdf899132016-11-12 15:16:30 -050074 * down all created worker threads, and releases all allocated resources.
Mark Sleef5f2be42006-09-05 21:05:31 +000075 * This method blocks for all worker threads to complete, thus it can
Marc Slemko3a3b53b2007-05-22 23:59:54 +000076 * potentially block forever if a worker thread is running a task that
Mark Sleef5f2be42006-09-05 21:05:31 +000077 * won't terminate.
James E. King, IIIdf899132016-11-12 15:16:30 -050078 *
79 * Worker threads will be joined depending on the threadFactory's detached
80 * disposition.
Mark Sleef5f2be42006-09-05 21:05:31 +000081 */
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000082 virtual void stop() = 0;
83
Konrad Grochowski16a23a62014-11-13 15:33:38 +010084 enum STATE { UNINITIALIZED, STARTING, STARTED, JOINING, STOPPING, STOPPED };
Marc Slemko3a3b53b2007-05-22 23:59:54 +000085
Roger Meier3b771a12010-11-17 22:11:26 +000086 virtual STATE state() const = 0;
Marc Slemkofe5ba12e2006-07-20 21:16:27 +000087
James E. King, IIIdf899132016-11-12 15:16:30 -050088 /**
89 * \returns the current thread factory
90 */
Mark Slee5ea15f92007-03-05 22:55:59 +000091 virtual boost::shared_ptr<ThreadFactory> threadFactory() const = 0;
Marc Slemko66949872006-07-15 01:52:39 +000092
James E. King, IIIdf899132016-11-12 15:16:30 -050093 /**
94 * Set the thread factory.
95 * \throws InvalidArgumentException if the new thread factory has a different
96 * detached disposition than the one replacing it
97 */
Mark Slee5ea15f92007-03-05 22:55:59 +000098 virtual void threadFactory(boost::shared_ptr<ThreadFactory> value) = 0;
Marc Slemko66949872006-07-15 01:52:39 +000099
James E. King, IIIdf899132016-11-12 15:16:30 -0500100 /**
101 * Adds worker thread(s).
102 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100103 virtual void addWorker(size_t value = 1) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000104
James E. King, IIIdf899132016-11-12 15:16:30 -0500105 /**
106 * Removes worker thread(s).
107 * Threads are joined if the thread factory detached disposition allows it.
108 * Blocks until the number of worker threads reaches the new limit.
109 * \param[in] value the number to remove
110 * \throws InvalidArgumentException if the value is greater than the number
111 * of workers
112 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100113 virtual void removeWorker(size_t value = 1) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000114
Mark Sleef5f2be42006-09-05 21:05:31 +0000115 /**
116 * Gets the current number of idle worker threads
117 */
Marc Slemko66949872006-07-15 01:52:39 +0000118 virtual size_t idleWorkerCount() const = 0;
119
Mark Sleef5f2be42006-09-05 21:05:31 +0000120 /**
121 * Gets the current number of total worker threads
122 */
Marc Slemko66949872006-07-15 01:52:39 +0000123 virtual size_t workerCount() const = 0;
124
Mark Sleef5f2be42006-09-05 21:05:31 +0000125 /**
126 * Gets the current number of pending tasks
127 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100128 virtual size_t pendingTaskCount() const = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000129
Mark Sleef5f2be42006-09-05 21:05:31 +0000130 /**
131 * Gets the current number of pending and executing tasks
132 */
Marc Slemko66949872006-07-15 01:52:39 +0000133 virtual size_t totalTaskCount() const = 0;
134
Mark Sleef5f2be42006-09-05 21:05:31 +0000135 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000136 * Gets the maximum pending task count. 0 indicates no maximum
Mark Sleef5f2be42006-09-05 21:05:31 +0000137 */
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000138 virtual size_t pendingTaskCountMax() const = 0;
139
140 /**
James E. King, IIIdf899132016-11-12 15:16:30 -0500141 * Gets the number of tasks which have been expired without being run
142 * since start() was called.
David Reiss068f4162010-03-09 05:19:45 +0000143 */
144 virtual size_t expiredTaskCount() = 0;
145
146 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000147 * Adds a task to be executed at some time in the future by a worker thread.
148 *
149 * This method will block if pendingTaskCountMax() in not zero and pendingTaskCount()
150 * is greater than or equalt to pendingTaskCountMax(). If this method is called in the
151 * context of a ThreadManager worker thread it will throw a
152 * TooManyPendingTasksException
153 *
154 * @param task The task to queue for execution
155 *
156 * @param timeout Time to wait in milliseconds to add a task when a pending-task-count
Aditya Agarwal4b6ff2d2007-12-25 22:58:50 +0000157 * is specified. Specific cases:
158 * timeout = 0 : Wait forever to queue task.
159 * timeout = -1 : Return immediately if pending task count exceeds specified max
David Reiss068f4162010-03-09 05:19:45 +0000160 * @param expiration when nonzero, the number of milliseconds the task is valid
161 * to be run; if exceeded, the task will be dropped off the queue and not run.
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000162 *
163 * @throws TooManyPendingTasksException Pending task count exceeds max pending task count
164 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100165 virtual void add(boost::shared_ptr<Runnable> task,
166 int64_t timeout = 0LL,
167 int64_t expiration = 0LL) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000168
Mark Sleef5f2be42006-09-05 21:05:31 +0000169 /**
170 * Removes a pending task
171 */
Mark Slee5ea15f92007-03-05 22:55:59 +0000172 virtual void remove(boost::shared_ptr<Runnable> task) = 0;
Marc Slemko66949872006-07-15 01:52:39 +0000173
David Reiss01fe1532010-03-09 05:19:25 +0000174 /**
175 * Remove the next pending task which would be run.
176 *
177 * @return the task removed.
178 */
179 virtual boost::shared_ptr<Runnable> removeNextPending() = 0;
180
David Reiss068f4162010-03-09 05:19:45 +0000181 /**
182 * Remove tasks from front of task queue that have expired.
183 */
184 virtual void removeExpiredTasks() = 0;
185
186 /**
187 * Set a callback to be called when a task is expired and not run.
188 *
189 * @param expireCallback a function called with the shared_ptr<Runnable> for
190 * the expired task.
191 */
192 virtual void setExpireCallback(ExpireCallback expireCallback) = 0;
193
Mark Slee5ea15f92007-03-05 22:55:59 +0000194 static boost::shared_ptr<ThreadManager> newThreadManager();
Marc Slemkod466b212006-07-20 00:04:18 +0000195
Mark Sleef5f2be42006-09-05 21:05:31 +0000196 /**
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000197 * Creates a simple thread manager the uses count number of worker threads and has
198 * a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit
199 * on pending tasks
Mark Sleef5f2be42006-09-05 21:05:31 +0000200 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100201 static boost::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count = 4,
202 size_t pendingTaskCountMax = 0);
Marc Slemko66949872006-07-15 01:52:39 +0000203
204 class Task;
Marc Slemko3a3b53b2007-05-22 23:59:54 +0000205
Marc Slemko66949872006-07-15 01:52:39 +0000206 class Worker;
207
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000208 class Impl;
Marc Slemko66949872006-07-15 01:52:39 +0000209};
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100210}
211}
212} // apache::thrift::concurrency
Marc Slemko66949872006-07-15 01:52:39 +0000213
Mark Sleef5f2be42006-09-05 21:05:31 +0000214#endif // #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_