2018-01-27 01:50:16 +08:00
|
|
|
#pragma once
|
|
|
|
|
2017-09-13 00:57:09 +08:00
|
|
|
#include <chrono>
|
2017-09-12 21:25:43 +08:00
|
|
|
#include <experimental/optional>
|
|
|
|
#include <map>
|
2017-09-13 00:57:09 +08:00
|
|
|
#include <random>
|
2017-08-30 23:17:43 +08:00
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include "communication/bolt/client.hpp"
|
2018-07-24 21:11:18 +08:00
|
|
|
#include "communication/bolt/v1/value.hpp"
|
2018-07-02 21:34:33 +08:00
|
|
|
#include "utils/algorithm.hpp"
|
2017-09-12 21:25:43 +08:00
|
|
|
#include "utils/exceptions.hpp"
|
2018-07-02 21:34:33 +08:00
|
|
|
#include "utils/thread/sync.hpp"
|
2017-09-27 20:02:24 +08:00
|
|
|
#include "utils/timer.hpp"
|
2017-08-30 23:17:43 +08:00
|
|
|
|
2018-06-20 23:44:47 +08:00
|
|
|
using communication::ClientContext;
|
2018-03-28 20:49:28 +08:00
|
|
|
using communication::bolt::Client;
|
2018-07-24 21:11:18 +08:00
|
|
|
using communication::bolt::Value;
|
2018-03-28 20:49:28 +08:00
|
|
|
using io::network::Endpoint;
|
2017-08-30 23:17:43 +08:00
|
|
|
|
2018-07-24 21:11:18 +08:00
|
|
|
void PrintJsonValue(std::ostream &os, const Value &value) {
|
2017-08-30 23:17:43 +08:00
|
|
|
switch (value.type()) {
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Null:
|
2017-08-30 23:17:43 +08:00
|
|
|
os << "null";
|
|
|
|
break;
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Bool:
|
2017-08-30 23:17:43 +08:00
|
|
|
os << (value.ValueBool() ? "true" : "false");
|
|
|
|
break;
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Int:
|
2017-08-30 23:17:43 +08:00
|
|
|
os << value.ValueInt();
|
|
|
|
break;
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Double:
|
2017-08-30 23:17:43 +08:00
|
|
|
os << value.ValueDouble();
|
|
|
|
break;
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::String:
|
2017-08-30 23:17:43 +08:00
|
|
|
os << "\"" << value.ValueString() << "\"";
|
|
|
|
break;
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::List:
|
2017-08-30 23:17:43 +08:00
|
|
|
os << "[";
|
2017-09-26 18:51:52 +08:00
|
|
|
utils::PrintIterable(os, value.ValueList(), ", ",
|
|
|
|
[](auto &stream, const auto &item) {
|
2018-07-24 21:11:18 +08:00
|
|
|
PrintJsonValue(stream, item);
|
2017-09-26 18:51:52 +08:00
|
|
|
});
|
2017-08-30 23:17:43 +08:00
|
|
|
os << "]";
|
|
|
|
break;
|
2018-07-24 21:11:18 +08:00
|
|
|
case Value::Type::Map:
|
2017-08-30 23:17:43 +08:00
|
|
|
os << "{";
|
2017-09-26 18:51:52 +08:00
|
|
|
utils::PrintIterable(os, value.ValueMap(), ", ",
|
|
|
|
[](auto &stream, const auto &pair) {
|
2018-07-24 21:11:18 +08:00
|
|
|
PrintJsonValue(stream, {pair.first});
|
2017-09-26 18:51:52 +08:00
|
|
|
stream << ": ";
|
2018-07-24 21:11:18 +08:00
|
|
|
PrintJsonValue(stream, pair.second);
|
2017-09-26 18:51:52 +08:00
|
|
|
});
|
2017-08-30 23:17:43 +08:00
|
|
|
os << "}";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
std::terminate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-06 02:11:52 +08:00
|
|
|
std::pair<communication::bolt::QueryData, int> ExecuteNTimesTillSuccess(
|
2018-03-28 20:49:28 +08:00
|
|
|
Client &client, const std::string &query,
|
2018-07-24 21:11:18 +08:00
|
|
|
const std::map<std::string, communication::bolt::Value> ¶ms,
|
2018-03-13 22:27:49 +08:00
|
|
|
int max_attempts) {
|
2017-09-13 00:57:09 +08:00
|
|
|
static thread_local std::mt19937 pseudo_rand_gen_{std::random_device{}()};
|
|
|
|
static thread_local std::uniform_int_distribution<> rand_dist_{10, 50};
|
2018-03-13 22:27:49 +08:00
|
|
|
int failed_attempts{0};
|
|
|
|
while (true) {
|
2017-08-30 23:17:43 +08:00
|
|
|
try {
|
2017-09-12 21:25:43 +08:00
|
|
|
auto ret = client.Execute(query, params);
|
2018-03-13 22:27:49 +08:00
|
|
|
return {ret, failed_attempts};
|
2017-09-12 21:25:43 +08:00
|
|
|
} catch (const utils::BasicException &e) {
|
Add deletion, more stats to card fraud and RWLock
Summary:
^^
this is a sample config to be used:
```
{
"num_workers": 1,
"cards_per_worker": 10001,
"pos_per_worker": 10001,
"fraud_probability": 0.01,
"hop_probability": 0.05,
"cleanup": {
"check_interval_sec": 10,
"tx_hi": 150000,
"tx_lo": 100000
},
"analytic": {
"query_interval_ms": 500,
"pos_limit": 10
}
}
```
I also added `RWLock` --- a wrapper around `pthread_rwlock`
Reviewers: mferencevic, mculinovic, florijan, teon.banek
Reviewed By: florijan
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1280
2018-03-14 20:47:18 +08:00
|
|
|
VLOG(0) << "Error: " << e.what();
|
2018-03-13 22:27:49 +08:00
|
|
|
if (++failed_attempts == max_attempts) {
|
|
|
|
LOG(WARNING) << query << " failed " << failed_attempts << "times";
|
|
|
|
throw;
|
|
|
|
}
|
2017-09-27 20:02:24 +08:00
|
|
|
utils::Timer t;
|
|
|
|
std::chrono::microseconds to_sleep(rand_dist_(pseudo_rand_gen_));
|
|
|
|
while (t.Elapsed() < to_sleep) {
|
2018-05-30 19:00:25 +08:00
|
|
|
utils::CpuRelax();
|
2017-09-27 20:02:24 +08:00
|
|
|
}
|
2017-08-30 23:17:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|