TaskOutcomeReader.cpp
Go to the documentation of this file.
1#include "TaskOutcomeReader.h"
2
3#include <iterator>
4
7
9
10#include <RobotAPI/libraries/armem_task_outcome/aron/TaskOutcome.aron.generated.h>
12
14{
16
19 {
21
23 qb.coreSegments().withName(properties().coreSegmentName);
24
27 {
28 if (not query.providerName.empty())
29 {
30 return coreSegmentQuery.providerSegments().withName(query.providerName);
31 }
32 return coreSegmentQuery.providerSegments().all();
33 }();
34
35 providerQuery.entities().all().snapshots().beforeOrAtTime(query.timestamp);
36
37 return qb;
38 }
39
40 std::vector<TaskOutcome>
42 const wm::ProviderSegment& providerSegment,
43 const DateTime& timestamp,
44 const Duration& maxAge,
45 const std::optional<TaskType>& taskTypeFilter,
46 const std::optional<TaskOutcomeType>& outcomeFilter) const
47 {
49 std::vector<TaskOutcome> outcomes;
50
51 providerSegment.forEachEntity(
52 [&](const wm::Entity& entity)
53 {
55
56 const auto& entitySnapshot = entity.getLatestSnapshot();
57
58 entitySnapshot.forEachInstance(
59 [&outcomes, &timestamp, &maxAge, &taskTypeFilter, &outcomeFilter](
60 const auto& entityInstance)
61 {
63
64 const core::time::Duration dtToNow =
65 timestamp - entityInstance.metadata().referencedTime;
66
67 if (dtToNow < maxAge and dtToNow.isPositive())
68 {
69 const auto aronDto =
71 entityInstance);
72 ARMARX_CHECK(aronDto) << "Failed casting to TaskOutcome";
73
74 TaskOutcome outcome;
75 fromAron(*aronDto, outcome);
76
77 // Client-side filtering
78 if (taskTypeFilter.has_value() &&
79 outcome.taskType != taskTypeFilter.value())
80 {
81 return;
82 }
83 if (outcomeFilter.has_value() &&
84 outcome.outcomeType != outcomeFilter.value())
85 {
86 return;
87 }
88
89 outcomes.push_back(outcome);
90 };
91 });
92 });
93
94 return outcomes;
95 }
96
97 std::string
99 {
100 return "mem.task_outcome.";
101 }
102
105 {
106 return {.memoryName = "TaskOutcome", .coreSegmentName = "TaskOutcome"};
107 }
108
111 {
113
114 const auto qb = buildQuery(query);
115
116 ARMARX_DEBUG << "[TaskOutcomeReader] query ... ";
117
118 const armem::client::QueryResult qResult = memoryReader().query(qb.buildQueryInput());
119
120 ARMARX_DEBUG << "[TaskOutcomeReader] result: " << qResult;
121
122 if (not qResult.success)
123 {
124 ARMARX_WARNING << "Failed to query data from memory: " << qResult.errorMessage;
125 return {.outcomes = {},
126 .status = Result::Status::Error,
127 .errorMessage = qResult.errorMessage};
128 }
129
131 const auto coreSegment = qResult.memory.getCoreSegment(properties().coreSegmentName);
132
133 if (query.providerName.empty())
134 {
136
137 std::vector<TaskOutcome> allOutcomes;
138
139 coreSegment.forEachProviderSegment(
140 [this, &allOutcomes, &query](const auto& providerSegment)
141 {
142 const std::vector<TaskOutcome> outcomes = asTaskOutcomes(
143 providerSegment,
144 query.timestamp,
145 query.maxAge,
146 query.taskTypeFilter,
147 query.outcomeFilter);
148 std::copy(
149 outcomes.begin(), outcomes.end(), std::back_inserter(allOutcomes));
150 });
151
152 if (allOutcomes.empty())
153 {
154 return {.outcomes = {},
155 .status = Result::Status::NoData,
156 .errorMessage = "No entities"};
157 }
158
159 return Result{.outcomes = allOutcomes, .status = Result::Status::Success};
160 }
161
163
164 if (not coreSegment.hasProviderSegment(query.providerName))
165 {
166 ARMARX_INFO << deactivateSpam(5) << "Provider segment `" << query.providerName
167 << "` does not exist (yet).";
168 return {.outcomes = {}, .status = Result::Status::NoData};
169 }
170
172
173 const wm::ProviderSegment& providerSegment =
174 coreSegment.getProviderSegment(query.providerName);
175
176 if (providerSegment.empty())
177 {
178 ARMARX_WARNING << "No entities.";
179 return {.outcomes = {},
180 .status = Result::Status::NoData,
181 .errorMessage = "No entities"};
182 }
183
184 try
185 {
187
188 const auto outcomes = asTaskOutcomes(
189 providerSegment,
190 query.timestamp,
191 query.maxAge,
192 query.taskTypeFilter,
193 query.outcomeFilter);
194 return Result{.outcomes = outcomes, .status = Result::Status::Success};
195 }
196 catch (...)
197 {
198 return Result{.status = Result::Status::Error,
199 .errorMessage = GetHandledExceptionString()};
200 }
201 }
202
203 std::vector<TaskOutcome>
205 const Duration& maxAge) const
206 {
207 Query q{.providerName = "",
208 .taskTypeFilter = taskType,
209 .outcomeFilter = std::nullopt,
210 .timestamp = armem::Time::Now(),
211 .maxAge = maxAge};
212
213 auto result = query(q);
214
215 if (result.status == Result::Status::Success)
216 {
217 return result.outcomes;
218 }
219
220 if (result.status == Result::Status::Error)
221 {
222 ARMARX_WARNING << "Failed to query task outcomes from memory";
223 }
224
225 return {};
226 }
227
228 std::vector<TaskOutcome>
230 {
231 Query q{.providerName = "",
232 .taskTypeFilter = std::nullopt,
233 .outcomeFilter = TaskOutcomeType::FAILURE,
234 .timestamp = armem::Time::Now(),
235 .maxAge = maxAge};
236
237 auto result = query(q);
238
239 if (result.status == Result::Status::Success)
240 {
241 return result.outcomes;
242 }
243
244 if (result.status == Result::Status::Error)
245 {
246 ARMARX_WARNING << "Failed to query task outcome failures from memory";
247 }
248
249 return {};
250 }
251
252} // namespace armarx::armem::task_outcome::client
std::string timestamp()
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
CoreSegmentT & getCoreSegment(const std::string &name)
Definition MemoryBase.h:134
QueryResult query(const QueryInput &input) const
Perform a query on the WM.
Definition Reader.cpp:119
The query::Builder class provides a fluent-style specification of hierarchical queries.
Definition Builder.h:22
CoreSegmentSelector & coreSegments()
Start specifying core segments.
Definition Builder.cpp:42
CoreSegmentSelector & withName(const std::string &name) override
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
SnapshotSelector & snapshots()
Start specifying entity snapshots.
Definition selectors.cpp:92
ProviderSegmentSelector & withName(const std::string &name) override
EntitySelector & entities()
Start specifying entities.
ProviderSegmentSelector & all() override
SnapshotSelector & beforeOrAtTime(Time timestamp)
Definition selectors.cpp:73
const armem::client::Reader & memoryReader() const
std::vector< TaskOutcome > queryByTaskType(TaskType taskType, const Duration &maxAge) const
std::vector< TaskOutcome > queryFailures(const Duration &maxAge) const
::armarx::armem::client::query::Builder buildQuery(const Query &query) const
std::vector< TaskOutcome > asTaskOutcomes(const wm::ProviderSegment &providerSegment, const DateTime &timestamp, const Duration &maxAge, const std::optional< TaskType > &taskTypeFilter, const std::optional< TaskOutcomeType > &outcomeFilter) const
Represents a point in time.
Definition DateTime.h:25
static DateTime Now()
Definition DateTime.cpp:51
Represents a duration.
Definition Duration.h:17
bool isPositive() const
Tests whether the duration is positive (value in µs > 0).
Definition Duration.cpp:168
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define q
void fromAron(const armarx::task_outcome::arondto::TaskOutcomeType &dto, TaskOutcomeType &bo)
armarx::core::time::Duration Duration
std::optional< AronClass > tryCast(const wm::EntityInstance &item)
Tries to cast a armem::EntityInstance to AronClass.
Definition util.h:45
std::string GetHandledExceptionString()
auto & getLatestSnapshot(int snapshotIndex=0)
Retrieve the latest entity snapshot.
Result of a QueryInput.
Definition Query.h:51
wm::Memory memory
The slice of the memory that matched the query.
Definition Query.h:58
#define ARMARX_TRACE
Definition trace.h:77