MADARA  3.1.8
KnowledgeBase.cpp
Go to the documentation of this file.
1 
4 #include "madara/logger/Logger.h"
5 
6 
7 #include <sstream>
8 #include <iostream>
9 
10 #include "ace/OS_NS_Thread.h"
11 #include "ace/High_Res_Timer.h"
12 #include "ace/OS_NS_sys_socket.h"
13 
14 namespace madara { namespace knowledge {
15 
16 #ifndef _MADARA_NO_KARL_
17 
20  CompiledExpression & expression,
21  const WaitSettings & settings)
22 {
23  KnowledgeRecord result;
24 
25  if (context_)
26  {
37  ACE_Time_Value current = ACE_High_Res_Timer::gettimeofday ();
38  ACE_Time_Value max_wait, sleep_time, next_epoch;
39  ACE_Time_Value poll_frequency, last = current;
40 
41  if (settings.poll_frequency >= 0)
42  {
43  max_wait.set (settings.max_wait_time);
44  max_wait = current + max_wait;
45 
46  poll_frequency.set (settings.poll_frequency);
47  next_epoch = current + poll_frequency;
48  }
49 
50  // print the post statement at highest log level (cannot be masked)
51  if (settings.pre_print_statement != "")
53 
54  // lock the context
55  context_->lock ();
56 
58  "KnowledgeBase::wait:" \
59  " waiting on %s\n", expression.logic.c_str ());
60 
61  KnowledgeRecord last_value = expression.expression.evaluate (settings);
62 
64  "KnowledgeBase::wait:" \
65  " completed first eval to get %s\n",
66  last_value.to_string ().c_str ());
67 
68  send_modifieds ("KnowledgeBase:wait", settings);
69 
70  context_->unlock ();
71 
72  current = ACE_High_Res_Timer::gettimeofday ();
73 
74  // wait for expression to be true
75  while (!last_value.to_integer () &&
76  (settings.max_wait_time < 0 || current < max_wait))
77  {
79  "KnowledgeBase::wait:" \
80  " current is %llu.%llu and max is %llu.%llu (poll freq is %f)\n",
81  (unsigned long long)current.sec (),
82  (unsigned long long)current.usec (),
83  (unsigned long long)max_wait.sec (),
84  (unsigned long long)max_wait.usec (),
85  settings.poll_frequency);
86 
88  "KnowledgeBase::wait:" \
89  " last value didn't result in success\n");
90 
91  // Unlike the other wait statements, we allow for a time based wait.
92  // To do this, we allow a user to specify a
93  if (settings.poll_frequency > 0)
94  {
95  if (current < next_epoch)
96  {
97  sleep_time = next_epoch - current;
98  madara::utility::sleep (sleep_time);
99  }
100 
101  next_epoch = next_epoch + poll_frequency;
102  }
103  else
104  context_->wait_for_change (true);
105 
106  // relock - basically we need to evaluate the tree again, and
107  // we can't have a bunch of people changing the variables as
108  // while we're evaluating the tree.
109  context_->lock ();
110 
111 
113  "KnowledgeBase::wait:" \
114  " waiting on %s\n", expression.logic.c_str ());
115 
116  last_value = expression.expression.evaluate (settings);
117 
119  "KnowledgeBase::wait:" \
120  " completed eval to get %s\n",
121  last_value.to_string ().c_str ());
122 
123  send_modifieds ("KnowledgeBase:wait", settings);
124 
125  context_->unlock ();
126  context_->signal ();
127 
128  // get current time
129  current = ACE_High_Res_Timer::gettimeofday ();
130 
131  } // end while (!last)
132 
133  if (current >= max_wait)
134  {
136  "KnowledgeBase::wait:" \
137  " Evaluate did not succeed. Timeout occurred\n");
138  }
139 
140  // print the post statement at highest log level (cannot be masked)
141  if (settings.post_print_statement != "")
143 
144  return last_value;
145  }
146  else if (impl_.get ())
147  {
148  result = impl_->wait (expression, settings);
149  }
150 
151  return result;
152 }
153 #endif // _MADARA_NO_KARL_
154 
155 } }
This class encapsulates an entry in a KnowledgeBase.
double max_wait_time
Maximum time to wait for an expression to become true (in seconds)
Definition: WaitSettings.h:113
void lock(void) const
Locks the mutex on this context.
std::string pre_print_statement
Statement to print before evaluations.
Definition: EvalSettings.h:119
int send_modifieds(const std::string &prefix="KnowledgeBase::send_modifieds", const EvalSettings &settings=EvalSettings())
Sends all modified variables through the attached transports.
void signal(bool lock=true) const
Signals that this thread is done with the context.
void print(unsigned int level) const
Atomically prints all variables and values in the context.
std::string logic
the logic that was compiled
MADARA_Export double sleep(double sleep_time)
Sleeps for a certain amount of time.
Definition: Utility.cpp:856
Compiled, optimized KaRL logic.
#define madara_logger_log(logger, level,...)
Fast version of the madara::logger::log method.
Definition: Logger.h:20
std::string post_print_statement
Statement to print after evaluations.
Definition: EvalSettings.h:124
std::shared_ptr< KnowledgeBaseImpl > impl_
Pointer to actual implementation, i.e., the "bridge", which is reference counted to automate memory m...
madara::expression::ExpressionTree expression
the expression tree
ThreadSafeContext * context_
A knowledge base can also be a facade for another knowledge base.
madara::knowledge::KnowledgeRecord wait(const std::string &expression, const WaitSettings &settings=WaitSettings())
Waits for an expression to be non-zero.
void unlock(void) const
Unlocks the mutex on this context.
double poll_frequency
Frequency to poll an expression for truth (in seconds)
Definition: WaitSettings.h:108
void wait_for_change(bool extra_release=false)
Wait for a change to happen to the context.
Provides functions and classes for the distributed knowledge base.
Copyright (c) 2015 Carnegie Mellon University.
logger::Logger & get_logger(void) const
Gets the logger used for information printing.
Encapsulates settings for a wait statement.
Definition: WaitSettings.h:23
madara::knowledge::KnowledgeRecord evaluate(const madara::knowledge::KnowledgeUpdateSettings &settings=knowledge::KnowledgeUpdateSettings())
Evaluates the expression tree.