131 lines
3.8 KiB
C++
131 lines
3.8 KiB
C++
// Copyright (2019-2023) Paul Scherrer Institute
|
|
// Using OpenAPI licensed with Apache License 2.0
|
|
|
|
#include <vector>
|
|
#include <csignal>
|
|
#include <fstream>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#include "../common/Logger.h"
|
|
#include "../common/NetworkAddressConvert.h"
|
|
|
|
#include "JFJochBrokerHttp.h"
|
|
|
|
#include "JFJochBrokerParser.h"
|
|
|
|
static Pistache::Http::Endpoint *httpEndpoint;
|
|
|
|
static void sigHandler [[noreturn]] (int sig){
|
|
switch(sig){
|
|
case SIGINT:
|
|
case SIGQUIT:
|
|
case SIGTERM:
|
|
case SIGHUP:
|
|
default:
|
|
httpEndpoint->shutdown();
|
|
break;
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
static void setUpUnixSignals(std::vector<int> quitSignals) {
|
|
sigset_t blocking_mask;
|
|
sigemptyset(&blocking_mask);
|
|
for (auto sig : quitSignals)
|
|
sigaddset(&blocking_mask, sig);
|
|
|
|
struct sigaction sa;
|
|
sa.sa_handler = sigHandler;
|
|
sa.sa_mask = blocking_mask;
|
|
sa.sa_flags = 0;
|
|
|
|
for (auto sig : quitSignals)
|
|
sigaction(sig, &sa, nullptr);
|
|
}
|
|
|
|
int main (int argc, char **argv) {
|
|
if (argc > 3) {
|
|
std::cout << "Usage ./jfjoch_broker <JSON config> {<TCP http port>}" << std::endl;
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
uint16_t http_port = 5232;
|
|
if (argc >= 3) http_port = atoi(argv[2]);
|
|
|
|
Logger logger("jfjoch_broker");
|
|
|
|
nlohmann::json input;
|
|
if (argc > 1) {
|
|
std::ifstream file(argv[1]);
|
|
try {
|
|
input = nlohmann::json::parse(file);
|
|
} catch (const nlohmann::json::exception &e) {
|
|
logger.Error("JSON Parsing exception: " + std::string(e.what()));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
} else {
|
|
logger.Error("Must provide JSON configuration file");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
std::unique_ptr<JFJochReceiverService> receiver;
|
|
std::unique_ptr<ImagePusher> image_pusher;
|
|
|
|
DiffractionExperiment experiment;
|
|
experiment.MaskChipEdges(true).MaskModuleEdges(true);
|
|
|
|
AcquisitionDeviceGroup aq_devices;
|
|
ParseAcquisitionDeviceGroup(input, "receiver", aq_devices);
|
|
if (aq_devices.size() > 0) {
|
|
experiment.DataStreams(aq_devices.size());
|
|
|
|
ParseImagePusher(input, image_pusher);
|
|
|
|
int32_t send_buffer_size_MiB = ParseInt32(input, "send_buffer_size_MiB", 2048);
|
|
receiver = std::make_unique<JFJochReceiverService>(aq_devices, logger, *image_pusher, send_buffer_size_MiB);
|
|
|
|
std::string numa_policy = ParseString(input, "numa_policy", "");
|
|
if (!numa_policy.empty())
|
|
receiver->NUMAPolicy(numa_policy);
|
|
|
|
receiver->NumThreads(ParseInt64(input, "receiver_threads", 64));
|
|
}
|
|
|
|
ParseFacilityConfiguration(input, "cfg", experiment);
|
|
|
|
logger.Info("Source {} Instrument {} Default rotation axis {:.2f},{:.2f},{:.2f}",
|
|
experiment.GetSourceName(), experiment.GetInstrumentName(),
|
|
experiment.GetDefaultRotationAxis().x,
|
|
experiment.GetDefaultRotationAxis().y,
|
|
experiment.GetDefaultRotationAxis().z);
|
|
|
|
Pistache::Address addr(Pistache::Ipv4::any(), Pistache::Port(http_port));
|
|
|
|
httpEndpoint = new Pistache::Http::Endpoint((addr));
|
|
|
|
auto router = std::make_shared<Pistache::Rest::Router>();
|
|
|
|
auto opts = Pistache::Http::Endpoint::options().threads(8).maxRequestSize(64*1024*1024);
|
|
opts.flags(Pistache::Tcp::Options::ReuseAddr);
|
|
httpEndpoint->init(opts);
|
|
|
|
std::vector<int> sigs{SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
|
setUpUnixSignals(sigs);
|
|
|
|
JFJochBrokerHttp broker(experiment, router);
|
|
broker.FrontendDirectory(input["frontend_directory"]);
|
|
ParseDetectorSetup(input, "detectors", broker);
|
|
|
|
if (input["verbose"].is_boolean()) {
|
|
logger.Verbose(input["verbose"]);
|
|
aq_devices.EnableLogging(&logger);
|
|
}
|
|
|
|
if (receiver)
|
|
broker.Services().Receiver(receiver.get());
|
|
|
|
httpEndpoint->setHandler(router->handler());
|
|
httpEndpoint->serve();
|
|
|
|
httpEndpoint->shutdown();
|
|
} |