MADARA  3.4.1
KnowledgeBase.cpp
Go to the documentation of this file.
1 
4 #include "madara/logger/Logger.h"
6 #include "ContextGuard.h"
8 
9 #include <sstream>
10 #include <iostream>
11 
12 namespace utility = madara::utility;
13 
15 
16 namespace madara
17 {
18 namespace knowledge
19 {
20 
21 #ifndef _MADARA_NO_KARL_
22 
25  CompiledExpression& expression, const WaitSettings& settings)
26 {
27  KnowledgeRecord result;
28 
29  if (context_)
30  {
41  EpochEnforcer enforcer(settings.poll_frequency, settings.max_wait_time);
42 
43  KnowledgeRecord last_value;
44 
45  // print the post statement at highest log level (cannot be masked)
46  if (settings.pre_print_statement != "")
48 
49  {
50  ContextGuard context_guard(*context_);
51 
53  "KnowledgeBase::wait:"
54  " waiting on %s\n",
55  expression.logic.c_str());
56 
57  last_value = expression.expression.evaluate(settings);
58 
60  "KnowledgeBase::wait:"
61  " completed first eval to get %s\n",
62  last_value.to_string().c_str());
63 
64  send_modifieds("KnowledgeBase:wait", settings);
65  }
66 
67  // wait for expression to be true
68  while (!last_value.to_integer() &&
69  (settings.max_wait_time < 0 || !enforcer.is_done()))
70  {
72  "KnowledgeBase::wait:"
73  " last value didn't result in success\n");
74 
75  // Unlike the other wait statements, we allow for a time based wait.
76  // To do this, we allow a user to specify a
77  if (settings.poll_frequency > 0)
78  {
79  enforcer.sleep_until_next();
80  }
81  else
83 
84  // relock - basically we need to evaluate the tree again, and
85  // we can't have a bunch of people changing the variables as
86  // while we're evaluating the tree.
87  {
88  ContextGuard context_guard(*context_);
89 
91  "KnowledgeBase::wait:"
92  " waiting on %s\n",
93  expression.logic.c_str());
94 
95  last_value = expression.expression.evaluate(settings);
96 
98  "KnowledgeBase::wait:"
99  " completed eval to get %s\n",
100  last_value.to_string().c_str());
101 
102  send_modifieds("KnowledgeBase:wait", settings);
103  }
104 
105  context_->signal();
106  } // end while (!last)
107 
108  if (enforcer.is_done())
109  {
111  "KnowledgeBase::wait:"
112  " Evaluate did not succeed. Timeout occurred\n");
113  }
114 
115  // print the post statement at highest log level (cannot be masked)
116  if (settings.post_print_statement != "")
118 
119  return last_value;
120  }
121  else if (impl_.get())
122  {
123  result = impl_->wait(expression, settings);
124  }
125 
126  return result;
127 }
128 #endif // _MADARA_NO_KARL_
129 }
130 } // namespace madara
utility::EpochEnforcer< std::chrono::steady_clock > EpochEnforcer
#define madara_logger_log(loggering, level,...)
Fast version of the madara::logger::log method.
Definition: Logger.h:20
madara::knowledge::KnowledgeRecord evaluate(const madara::knowledge::KnowledgeUpdateSettings &settings=knowledge::KnowledgeUpdateSettings())
Evaluates the expression tree.
Compiled, optimized KaRL logic.
std::string logic
the logic that was compiled
madara::expression::ExpressionTree expression
the expression tree
A thread-safe guard for a context or knowledge base.
Definition: ContextGuard.h:24
int send_modifieds(const std::string &prefix="KnowledgeBase::send_modifieds", const EvalSettings &settings=EvalSettings::SEND)
Sends all modified variables through the attached transports.
madara::knowledge::KnowledgeRecord wait(const std::string &expression, const WaitSettings &settings=WaitSettings())
Waits for an expression to be non-zero.
ThreadSafeContext * context_
A knowledge base can also be a facade for another knowledge base.
std::shared_ptr< KnowledgeBaseImpl > impl_
Pointer to actual implementation, i.e., the "bridge", which is reference counted to automate memory m...
This class encapsulates an entry in a KnowledgeBase.
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
Integer to_integer(void) const
converts the value to an integer.
logger::Logger & get_logger(void) const
Gets the logger used for information printing.
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.
void wait_for_change(bool extra_release=false)
Wait for a change to happen to the context.
Enforces a periodic epoch.
Definition: EpochEnforcer.h:18
bool is_done(void) const
Checks to see if max duration is finished.
void sleep_until_next(void)
Sleeps until the next epoch.
Definition: EpochEnforcer.h:91
Provides functions and classes for the distributed knowledge base.
Provides utility functions and classes for common tasks and needs.
Definition: IteratorImpl.h:15
Copyright(c) 2020 Galois.
std::string post_print_statement
Statement to print after evaluations.
Definition: EvalSettings.h:151
std::string pre_print_statement
Statement to print before evaluations.
Definition: EvalSettings.h:146
Encapsulates settings for a wait statement.
Definition: WaitSettings.h:25
double max_wait_time
Maximum time to wait for an expression to become true (in seconds)
Definition: WaitSettings.h:136
double poll_frequency
Frequency to poll an expression for truth (in seconds)
Definition: WaitSettings.h:131