NCBI C++ ToolKit
app_task_impl.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: app_task_impl.cpp 40283 2018-01-19 18:08:34Z katargir $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Andrey Yazhuk
27  *
28  * File Description:
29  *
30  *
31  */
32 
33 #include <ncbi_pch.hpp>
34 
37 
40 
41 
43 
44 #define TASK_CATCH_AND_REPORT(message, task) \
45  catch (CException& e) { \
46  ERR_POST(message << task.GetDescr()); \
47  ERR_POST(e.ReportAll()); \
48  } catch (std::exception& ee) { \
49  ERR_POST(message << task.GetDescr() << ee.what()); \
50  }
51 
52 ///////////////////////////////////////////////////////////////////////////////
53 /// CAppTask
54 CAppTask::CAppTask(const string& descr, bool visible, int display_delay)
55 : m_Listener(NULL),
56  m_State(eInitial),
57  m_Visible(visible),
58  m_Descr(descr),
59  m_DisplayDelay(display_delay)
60 {
61 }
62 
63 
64 static const char* kChildFailed =
65  "CAppTask - unexpected exception while executing a child task.";
66 
67 
69 {
70  //LOG_POST("CAppTask::Run() - BEGIN");
71 
72  // init Time
74  m_State = eRunning;
75  // TODO init start time
76 
77  ETaskState new_state = eFailed; // we are pessimistic
78  try {
79  new_state = x_Run();
80  }
82 
83  m_State = new_state;
84  //LOG_POST("CAppTask::Run() - END");
85  return m_State;
86 }
87 
88 
90 {
91  _ASSERT(false); // implement in derived classes or override Run()
92  return eCompleted;
93 }
94 
95 
97 {
98  return m_State == eCompleted || m_State == eFailed || m_State == eCanceled;
99 }
100 
101 
103 {
104  return m_State;
105 }
106 
107 
109 {
110  // not needed for task that do not support background execution
111 }
112 
114 {
115  // override to implement cleanup procedures
116 }
117 
119 {
120  return m_Visible;
121 }
122 
124 {
125  return m_DisplayDelay;
126 }
127 
128 string CAppTask::GetDescr() const
129 {
130  return m_Descr;
131 }
132 
133 
135 {
136  // trivial implementation - simply return the state
137  // override this function to return more detailed description
138  return StateToString(m_State);
139 }
140 
141 
143 {
144  m_Listener = listener;
145 }
146 
147 
149 {
150  return NULL;
151 }
152 
153 
155 {
156  static string sInvalid = "Invalid";
157  static string sInitial = "Initial";
158  static string sBackgrounded = "Running";
159  static string sCompleted = "Completed";
160  static string sFailed = "Failed";
161  static string sCanceled = "Canceled";
162 
163  switch(state) {
164  case eInvalid:
165  return sInvalid;
166  case eInitial:
167  return sInitial;
168  case eBackgrounded:
169  return sBackgrounded;
170  case eCompleted:
171  return sCompleted;
172  case eFailed:
173  return sFailed;
174  case eCanceled:
175  return sCanceled;
176  default:
177  return "Unknown State";
178  }
179 }
180 
181 ///////////////////////////////////////////////////////////////////////////////
182 /// CCompositeAppTask
183 
186  CAppTaskServiceEvent::eWakeUpSignal,
187  CAppTaskServiceEvent::eTaskCanceled,
188  &CCompositeAppTask::OnTaskEvent)
190 
191 
192 CCompositeAppTask::CCompositeAppTask(const string& descr, bool visible)
193 : CAppTask(descr, visible)
194 {
195 }
196 
197 
199 {
200  if(m_State == eInitial) {
201  /// this is the first call to Run() - we need to start the task
202  m_State = eRunning;
203  }
204  if(m_State == eRunning || m_State == eBackgrounded) {
205  /// execute child tasks until they all completed or
206  /// until one of them backgrounds or fails
207  bool stop = false;
208  while( ! stop && x_GetCurrentSubTask()) {
209  // set pessimistic defaults
211  stop = true;
212 
213  try {
214  TTaskRef r_task = x_GetCurrentSubTask();
215  r_task->SetListener(this); // we will be listening on child tasks
216 
218 
219  switch(state) {
220  case eCompleted:
221  r_task->SetListener(NULL);
222  x_NextSubTask();
223  stop = false; // continue execution
224  break;
225  case eBackgrounded:
226  // stop execution until background process finishes
228  break;
229  case eFailed:
230  r_task->SetListener(NULL);
231  m_State = eFailed;
232  break;
233  default:
234  _ASSERT(false);
235  r_task->SetListener(NULL);
236  m_State = eFailed;
237  break;
238  }
239  }
241  }
242  if( ! stop) {
244  }
245  } else {
246  _ASSERT(false); // unexpected state
247  m_State = eFailed;
248  }
249  //LOG_POST("CCompositeAppTask::Run() - finished");
250  return m_State;
251 }
252 
253 
255 {
256  return x_GetCurrentSubTask()->Run();
257 }
258 
259 
261 {
262  if(m_State == eBackgrounded) {
264 
265  // listener is off - task is not needed
266  if (!m_Listener) {
267  task->SetListener(NULL);
268  }
269 
270  task->CancelBackgrounded();
271  }
272 }
273 
274 
276 {
277  CAppTaskServiceEvent* tm_evt = dynamic_cast<CAppTaskServiceEvent*>(event);
278  _ASSERT(tm_evt);
279 
280  if(tm_evt) {
281  CIRef<IAppTask> task = tm_evt->GetTask();
282 
284  _ASSERT(task == x_GetCurrentSubTask());
286 
288  CRef<CEvent> evt(new CAppTaskServiceEvent(*this, type));
289  m_Listener->Post(evt);
290  }
291 }
292 
293 
#define TASK_CATCH_AND_REPORT(message, task)
ON_EVENT_RANGE(CAppTaskServiceEvent, CAppTaskServiceEvent::eWakeUpSignal, CAppTaskServiceEvent::eTaskCanceled, &CCompositeAppTask::OnTaskEvent) CCompositeAppTask
CCompositeAppTask.
static const char * kChildFailed
CAppTaskServiceEvent.
CAppTask - default implementation of IAppTask, use it as a base class for custom tasks.
int m_DisplayDelay
tasks display delay
virtual void SetListener(CEventHandler *handler)
set a Listener; this allows a taks running in background to notify the Listener (usually Task Manager...
virtual IEventLogAction * CreateEventLogAction()
returns an action for activating task results (optional, can return NULL)
virtual bool IsVisible()
returns true if the task should be visible in UI visible task shall represent operations understood b...
virtual ETaskState Run()
execute the task, this function is called on the main UI thread if a task needs to execute in backgro...
virtual ETaskState GetState()
returns the current task state
ETaskState m_State
static string StateToString(ETaskState state)
CAppTask(const string &descr=kEmptyStr, bool visible=true, int display_delay=0)
CAppTask.
virtual bool x_IsFiniteState()
CEventHandler * m_Listener
virtual void OnCancel()
this will be called on pending tasks that will be removed from the queue and won't get a chance to ru...
virtual string GetDescr() const
returns a human-readable description of the Task (optional)
virtual ETaskState x_Run()
override this function in derived classes
const bool m_Visible
indicates whether the task is visible
virtual void CancelBackgrounded()
make a request to cancel backgrounded task (not called for foreground tasks)
virtual string GetStatusText() const
returns human-readable text describing the current task state
string m_Descr
task description
int GetStatusDisplayDelay()
returns delay in seconds used for certain fast (and not very important tasks) to only show its status...
CCompositeAppTask - an application task that consists of subtasks.
void OnTaskEvent(CEvent *event)
virtual TTaskRef x_NextSubTask()=0
prepares the next subtask (makes it current), this function is used for iterating subtasks.
virtual ETaskState x_RunCurrentSubTask()
runs the current subtask; one may override this function in order to perform special pre-execution or...
virtual void CancelBackgrounded()
make a request to cancel backgrounded task (not called for foreground tasks)
virtual ETaskState Run()
execute the task, this function is called on the main UI thread if a task needs to execute in backgro...
virtual TTaskRef x_GetCurrentSubTask()=0
returns a references to the current subtask
CEventHandler.
CEvent - generic event implementation TODO TODO - Attachments.
Definition: event.hpp:86
#define NULL
Definition: ncbistd.hpp:225
ETaskState
List of task states defining the task management FSM.
Definition: app_task.hpp:87
CIRef< IAppTask > GetTask()
@ eCanceled
canceled by Task Manager
Definition: app_task.hpp:94
@ eBackgrounded
task is executing in background
Definition: app_task.hpp:91
@ eInvalid
Definition: app_task.hpp:88
@ eFailed
failed during execution
Definition: app_task.hpp:93
@ eCompleted
successfully finished
Definition: app_task.hpp:92
@ eInitial
has not been executed yet
Definition: app_task.hpp:89
@ eRunning
task is executing on the main UI thread
Definition: app_task.hpp:90
const TEventID GetID(void) const
Inline Implementation.
Definition: event.hpp:164
void Post(CRef< CEvent > evt, EDispatch disp_how=eDispatch_Default, int pool_name=ePool_Default)
Handles an event asynchronously (process and/or dispatch).
#define END_EVENT_MAP()
Ends definition of Command Map.
#define BEGIN_EVENT_MAP(thisClass, baseClass)
Begins definition of Command Map for CEventHandler-derived class.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
Definition: type.c:6
#define _ASSERT
#define const
Definition: zconf.h:232
Modified on Wed Apr 17 13:10:17 2024 by modify_doxy.py rev. 669887