diff --git a/Documentation/Books/AQL/Functions/String.mdpp b/Documentation/Books/AQL/Functions/String.mdpp index 044a664699..cb6c316373 100644 --- a/Documentation/Books/AQL/Functions/String.mdpp +++ b/Documentation/Books/AQL/Functions/String.mdpp @@ -267,9 +267,9 @@ RANDOM_TOKEN(8) // "zGl09z42" RANDOM_TOKEN(8) // "m9w50Ft9" ``` -!SUBSECTION REGEX() +!SUBSECTION REGEX_MATCH() -`REGEX(text, search, caseInsensitive) → bool` +`REGEX_MATCH(text, search, caseInsensitive) → bool` Check whether the pattern *search* is contained in the string *text*, using regular expression matching. @@ -327,9 +327,9 @@ If the regular expression in *search* is invalid, a warning will be raised and the function will return *false*. ```js -REGEX("the quick brown fox", "the.*fox") // true -REGEX("the quick brown fox", "^(a|the)\s+(quick|slow).*f.x$") // true -REGEX("the\nquick\nbrown\nfox", "^the(\n[a-w]+)+\nfox$") // true +REGEX_MATCH("the quick brown fox", "the.*fox") // true +REGEX_MATCH("the quick brown fox", "^(a|the)\s+(quick|slow).*f.x$") // true +REGEX_MATCH("the\nquick\nbrown\nfox", "^the(\n[a-w]+)+\nfox$") // true ``` !SUBSECTION REVERSE() diff --git a/Documentation/Books/Manual/Deployment/Mesos.mdpp b/Documentation/Books/Manual/Deployment/Mesos.mdpp index e651f2d86c..de3d4c71fb 100644 --- a/Documentation/Books/Manual/Deployment/Mesos.mdpp +++ b/Documentation/Books/Manual/Deployment/Mesos.mdpp @@ -1,52 +1,154 @@ !SECTION Distributed deployment using Apache Mesos -Philosophie: Es muss extrem einfach aussehen, trotzdem sollte die Section -hinreichend viel Detailinformation liefern. Ich weiß, dass das ein -Widerspruch ist. +TODO: Intro (vom Rechner) !SUBSECTION DC/OS -Explain that ArangoDB is in "the universe" and can be launched under -"Services" in the UI. +DC/OS is the recommended way to install a cluster as it eases much of the process to install a Mesos cluster. You can deploy it very quickly on a variety of cloud hosters or setup your own DC/OS locally. DC/OS is a set of tools built on top of Apache Mesos. Apache Mesos is a so called "Distributed Cluster Operation System" and the core of DC/OS. Apache Mesos has the concept of so called [persistent volumes](http://mesos.apache.org/documentation/latest/persistent-volume/) which make it perfectly suitable for a database. -Show how one reaches the coordinator UI via the DC/OS UI after deployment. +!SUBSUBSECTION Installing -Explain about scaling up and down via the UI. +DC/OS comes with its own package management. Packages can be installed from the so called "Universe". As an official DC/OS partner ArangoDB can be installed from there straight away. -Explain configuration options or link to some place where they are -explained. +1. Installing via DC/OS UI + 1. Go to https://dcos.io and prepare a cluster + 2. Open your browser and go to the DC/OS admin interface + 3. Open the "Universe" tab + 4. Locate arangodb and hit "Install Package" + 5. Optionally review the settings (Advanced Installation) + 6. Press "Install Package" -Explain about the `dcos` CLI and the ArangoDB `dcos`-subcommand. +2. Installing via DC/OS Commandline -Explain how to shut down an ArangoDB cluster cleanly. + 1. Install the [dcos cli](https://docs.mesosphere.com/usage/cli/) + 2. Open a terminal and issue `dcos install arangodb` + +Both options are essentially doing the same in the background. Both are starting ArangoDB with its default options set. To review the default options click "Advanced Installation" in the webinterface or type `dcos package describe --config arangodb`. -Say that ArangoDB uses persistent volumes, explain advantage. +To get an explanation of the various command line options please check the latest options here (choose the most recent number and have a look at config.json): -Say that this makes it impossible to deploy ArangoDB to "public Mesos Agents". -Explain how to setup a marathon-lb load balancer to reach the coordinators -either from within the DC/OS cluster or from the outside (via public slaves). +https://github.com/mesosphere/universe/tree/version-3.x/repo/packages/A/arangodb -Explain authentication setup (once we have it). +Alternatively check the DC/OS webinterface. Hit installing ArangoDB on the "Services" tab and examine "Advanced Installation". -Staubsauger? +After installing DC/OS will start deploying the ArangoDB cluster on the DC/OS cluster. You can watch ArangoDB starting on the "Services" tab in the webinterface. Once it is listed as healthy click the link next to it and you should see the ArangoDB webinterface. + +!SUBSUBSECTION While running + +!SUBSUBSUBSECTION ArangoDB Mesos framework +While ArangoDB is deployed Mesos will keep your cluster running. The web interface has many monitoring facilities so be sure to make yourself familiar with the DC/OS webinterface. As a fault tolerant system Mesos will take care of most failure scenarios automatically. Mesos does that by running ArangoDB as a so called "framework". This framework has been specifically built to keep ArangoDB running in a healthy condition on the Mesos cluster. From time to time a task might fail. The ArangoDB framework will then take care of rescheduling the failed task. As it knows about the very specifics of each cluster task and its role it will automatically take care of most failure scenarios. + +To inspect what the framework is doing go to `WEBINTERFACEURL`/mesos in your browser. Locate the task "arangodb" and inspect stderr in the "Sandbox". This can be of interest for example when a slave got lost and the framework is rescheduling the task. + +!SUBSUBSUBSECTION Using ArangoDB + +To use ArangoDB as a datastore in your DC/OS cluster you can facilitate the service discovery of DC/OS. Assuming you deployed a standard ArangoDB cluster the [mesos dns](https://github.com/mesosphere/mesos-dns) will know about `arangodb.mesos`. By doing a SRV DNS request (check the documentation of mesos dns) you can find out the port where the internal HAProxy of ArangoDB is running. This will offer a round robin load balancer to access all ArangoDB coordinators. + +!SUBSUBSUBSECTION Scaling ArangoDB + +To change the settings of your ArangoDB Cluster access the ArangoDB UI and hit "Nodes". On the scale tab you will have the ability to scale your cluster up and down. + +After changing the settings the ArangoDB framework will take care of the rest. Scaling your cluster up is generally a straightforward operation as Mesos will simply launch another task and be done with it. Scaling down is a bit more complicated as the data first has to be moved to some other place so that will naturally take somewhat longer. + +Please note that scaling operations might not always work. For example if the underlying Mesos cluster is completely saturated with tasks scaling up will not be possible. Scaling down might also fail due to not being able to move all shards of a DBServer to a new destination because of size limitations. Be sure to check the output of the ArangoDB framework. + +!SUBSUBSECTION Deinstallation + +Deinstalling ArangoDB is a bit more difficult as there is much state being kept in the Mesos cluster which is not automatically cleaned up. To deinstall from the command line use the following one liner: + +`dcos arangodb uninstall ; dcos package uninstall arangodb` + +This will first cleanup the state in the cluster and then uninstall arangodb. + +!SUBSUBSUBSECTION arangodb-cleanup-framework + +Should you forget to cleanup the state you can do so later by using the [arangodb-cleanup-framework](https://github.com/arangodb/arangodb-cleanup-framework/) container. Otherwise you might not be able to deploy a new arangodb installation. + +The cleanup framework will announce itself as a normal ArangoDB. Mesos will recognize this and offer all persistent volumes it still has for ArangoDB to this framework. The cleanup framework will then properly free the persistent volumes. Finally it will clean up any state left in zookeeper (the central configuration manager in a Mesos cluster). + +To deploy follow the instructions in the github repository. After deploying watch the output in the sandbox of the Mesos webinterface. After a while there shouldn't be any persistent resource offers anymore as everything was cleaned up. After that you can delete the cleanup framework again via marathon. !SUBSECTION Apache Mesos and Marathon -Explain how to launch an ArangoDB cluster via Marathon in an Apache -Mesos cluster. +You can also install ArangoDB on a bare Apache Mesos cluster provided that marathon is running on it. -Explain configuration options or link to some place where they are -explained. +Doing so has the following downsides: -Show how one reaches the coordinator UI, HOW DOES THIS ACTUALLY WORK? -DO WE NEED EXPLAIN ABOUT sshuttle? +1. Manual Mesos cluster setup +1. You need to implement your own service discovery +1. You are missing the dcos cli +1. Install and Deinstall are tedious +1. You need to setup some kind of proxy tunnel to access arangodb from the outside +1. Sparse monitoring capabilities -Mention scaling up and down as in DC/OS case. +However these are things which do not influence ArangoDB itself and operating your cluster like this is fully supported. -Explain how to shut down an ArangoDB cluster cleanly. +!SUBSUBSECTION Installing via Marathon -Explain authentication setup (once we have it) or say it is exactly as -in the DC/OS case. +To install ArangoDB via marathon you need a proper config file: -Staubsauger? Deployment via Marathon. +``` +{ + "id": "arangodb", + "cpus": 0.25, + "mem": 256.0, + "ports": [0, 0, 0], + "instances": 1, + "args": [ + "framework", + "--framework_name=arangodb", + "--master=zk://172.17.0.2:2181/mesos", + "--zk=zk://172.17.0.2:2181/arangodb", + "--user=", + "--principal=pri", + "--role=arangodb", + "--mode=cluster", + "--async_replication=true", + "--minimal_resources_agent=mem(*):512;cpus(*):0.25;disk(*):512", + "--minimal_resources_dbserver=mem(*):512;cpus(*):0.25;disk(*):1024", + "--minimal_resources_secondary=mem(*):512;cpus(*):0.25;disk(*):1024", + "--minimal_resources_coordinator=mem(*):512;cpus(*):0.25;disk(*):1024", + "--nr_agents=1", + "--nr_dbservers=2", + "--nr_coordinators=2", + "--failover_timeout=86400", + "--arangodb_image=arangodb/arangodb-mesos:3.0", + "--secondaries_with_dbservers=false", + "--coordinators_with_dbservers=false" + ], + "container": { + "type": "DOCKER", + "docker": { + "image": "arangodb/arangodb-mesos-framework:3.0", + "network": "HOST" + } + }, + "healthChecks": [ + { + "protocol": "HTTP", + "path": "/framework/v1/health.json", + "gracePeriodSeconds": 3, + "intervalSeconds": 10, + "portIndex": 0, + "timeoutSeconds": 10, + "maxConsecutiveFailures": 0 + } + ] +} +``` +Carefully review the settings (especially the IPs and the resources). Then you can deploy to marathon: + +`curl -X POST -H "Content-Type: application/json" http://url-of-marathon/v2/apps -d @arangodb3.json` + +Alternatively use the webinterface of marathon to deploy ArangoDB. + +!SUBSUBSECTION Deinstallation via Marathon + +As with DC/OS you first need to properly cleanup any state leftovers. + +The easiest is to simply delete arangodb and then deploy the cleanup-framework (see section arangodb-cleanup-framework). + +!SUBSECTION Configuration options + +The Arangodb Mesos framework has a ton of different options which are listed and described here: https://github.com/arangodb/arangodb-mesos-framework/tree/3.0 \ No newline at end of file diff --git a/arangod/Actions/ActionFeature.cpp b/arangod/Actions/ActionFeature.cpp index 9a8ce1ed26..4f2a2db811 100644 --- a/arangod/Actions/ActionFeature.cpp +++ b/arangod/Actions/ActionFeature.cpp @@ -65,7 +65,7 @@ void ActionFeature::start() { nullptr); } -void ActionFeature::stop() { +void ActionFeature::unprepare() { TRI_CleanupActions(); ACTION = nullptr; diff --git a/arangod/Actions/ActionFeature.h b/arangod/Actions/ActionFeature.h index fbae1518b0..724b0e555a 100644 --- a/arangod/Actions/ActionFeature.h +++ b/arangod/Actions/ActionFeature.h @@ -36,7 +36,7 @@ class ActionFeature final : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; public: bool allowUseDatabase() { return _allowUseDatabase; } diff --git a/arangod/Aql/FunctionDefinitions.cpp b/arangod/Aql/FunctionDefinitions.cpp index 72940723df..d63fb5d2dc 100644 --- a/arangod/Aql/FunctionDefinitions.cpp +++ b/arangod/Aql/FunctionDefinitions.cpp @@ -177,8 +177,8 @@ struct FunctionDefiner { false, true, true, &Functions::Contains}); add({"LIKE", "AQL_LIKE", "s,r|b", true, true, false, true, true, &Functions::Like}); - add({"REGEX", "AQL_REGEX", "s,r|b", true, true, false, true, - true, &Functions::Regex}); + add({"REGEX_MATCH", "AQL_REGEX_MATCH", "s,r|b", true, true, false, true, + true, &Functions::RegexMatch}); add({"LEFT", "AQL_LEFT", "s,n", true, true, false, true, true}); add({"RIGHT", "AQL_RIGHT", "s,n", true, true, false, true, true}); add({"TRIM", "AQL_TRIM", "s|ns", true, true, false, true, true}); diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 13244f22f3..61de94d90c 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -1419,11 +1419,11 @@ AqlValue Functions::Like(arangodb::aql::Query* query, return AqlValue(result); } -/// @brief function REGEX -AqlValue Functions::Regex(arangodb::aql::Query* query, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { - ValidateParameters(parameters, "REGEX", 2, 3); +/// @brief function REGEX_MATCH +AqlValue Functions::RegexMatch(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + ValidateParameters(parameters, "REGEX_MATCH", 2, 3); bool const caseInsensitive = GetBooleanParameter(trx, parameters, 2, false); StringBufferLeaser buffer(trx); arangodb::basics::VPackStringBufferAdapter adapter(buffer->stringBuffer()); @@ -1464,7 +1464,7 @@ AqlValue Functions::Regex(arangodb::aql::Query* query, if (matcher == nullptr) { // compiling regular expression failed - RegisterWarning(query, "REGEX", TRI_ERROR_QUERY_INVALID_REGEX); + RegisterWarning(query, "REGEX_MATCH", TRI_ERROR_QUERY_INVALID_REGEX); return AqlValue(arangodb::basics::VelocyPackHelper::NullValue()); } @@ -1479,7 +1479,7 @@ AqlValue Functions::Regex(arangodb::aql::Query* query, if (error) { // compiling regular expression failed - RegisterWarning(query, "REGEX", TRI_ERROR_QUERY_INVALID_REGEX); + RegisterWarning(query, "REGEX_MATCH", TRI_ERROR_QUERY_INVALID_REGEX); return AqlValue(arangodb::basics::VelocyPackHelper::NullValue()); } diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index cec9b63f95..63ae304902 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -97,7 +97,7 @@ struct Functions { VPackFunctionParameters const&); static AqlValue Like(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); - static AqlValue Regex(arangodb::aql::Query*, arangodb::AqlTransaction*, + static AqlValue RegexMatch(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); static AqlValue Passthru(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); diff --git a/arangod/Dispatcher/DispatcherFeature.cpp b/arangod/Dispatcher/DispatcherFeature.cpp index 2c8e84bbf8..56fca43588 100644 --- a/arangod/Dispatcher/DispatcherFeature.cpp +++ b/arangod/Dispatcher/DispatcherFeature.cpp @@ -157,7 +157,9 @@ void DispatcherFeature::stop() { } _dispatcher->shutdown(); +} +void DispatcherFeature::unprepare() { DISPATCHER = nullptr; } diff --git a/arangod/Dispatcher/DispatcherFeature.h b/arangod/Dispatcher/DispatcherFeature.h index 11bd697a18..df9172d5a7 100644 --- a/arangod/Dispatcher/DispatcherFeature.h +++ b/arangod/Dispatcher/DispatcherFeature.h @@ -49,6 +49,7 @@ class DispatcherFeature final void start() override final; void beginShutdown() override final; void stop() override final; + void unprepare() override final; private: uint64_t _nrStandardThreads; diff --git a/arangod/Indexes/RocksDBFeature.cpp b/arangod/Indexes/RocksDBFeature.cpp index 8126d8d3ea..c877ce89ab 100644 --- a/arangod/Indexes/RocksDBFeature.cpp +++ b/arangod/Indexes/RocksDBFeature.cpp @@ -257,7 +257,7 @@ void RocksDBFeature::start() { } } -void RocksDBFeature::stop() { +void RocksDBFeature::unprepare() { if (!isEnabled()) { return; } diff --git a/arangod/Indexes/RocksDBFeature.h b/arangod/Indexes/RocksDBFeature.h index 2e75f5884a..b77c78110a 100644 --- a/arangod/Indexes/RocksDBFeature.h +++ b/arangod/Indexes/RocksDBFeature.h @@ -45,7 +45,7 @@ class RocksDBFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; inline rocksdb::OptimisticTransactionDB* db() const { return _db; } inline RocksDBKeyComparator* comparator() const { return _comparator; } diff --git a/arangod/RestServer/BootstrapFeature.h b/arangod/RestServer/BootstrapFeature.h index ce41ea4db0..21f9ddbb99 100644 --- a/arangod/RestServer/BootstrapFeature.h +++ b/arangod/RestServer/BootstrapFeature.h @@ -34,6 +34,7 @@ class BootstrapFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void start() override final; void stop() override final; + bool isReady() const { return _isReady; } diff --git a/arangod/RestServer/ConsoleFeature.cpp b/arangod/RestServer/ConsoleFeature.cpp index 0ce35fcc35..13e6f61381 100644 --- a/arangod/RestServer/ConsoleFeature.cpp +++ b/arangod/RestServer/ConsoleFeature.cpp @@ -73,6 +73,8 @@ void ConsoleFeature::stop() { while (_consoleThread->isRunning() && ++iterations < 30) { usleep(100 * 1000); // spin while console is still needed } +} +void ConsoleFeature::unprepare() { std::cout << std::endl << TRI_BYE_MESSAGE << std::endl; } diff --git a/arangod/RestServer/ConsoleFeature.h b/arangod/RestServer/ConsoleFeature.h index 997c1aa40b..63e9f56609 100644 --- a/arangod/RestServer/ConsoleFeature.h +++ b/arangod/RestServer/ConsoleFeature.h @@ -37,6 +37,7 @@ class ConsoleFeature final : public application_features::ApplicationFeature { public: void start() override final; void stop() override final; + void unprepare() override final; private: OperationMode _operationMode; diff --git a/arangod/RestServer/DatabaseFeature.cpp b/arangod/RestServer/DatabaseFeature.cpp index b87380929f..859a7e6f7d 100644 --- a/arangod/RestServer/DatabaseFeature.cpp +++ b/arangod/RestServer/DatabaseFeature.cpp @@ -171,7 +171,7 @@ void DatabaseFeature::start() { } } -void DatabaseFeature::stop() { +void DatabaseFeature::unprepare() { // close all databases closeDatabases(); diff --git a/arangod/RestServer/DatabaseFeature.h b/arangod/RestServer/DatabaseFeature.h index 017968a0a4..36cf9c610f 100644 --- a/arangod/RestServer/DatabaseFeature.h +++ b/arangod/RestServer/DatabaseFeature.h @@ -39,7 +39,7 @@ class DatabaseFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; public: TRI_vocbase_t* vocbase() const { return _vocbase; } diff --git a/arangod/RestServer/DatabaseServerFeature.cpp b/arangod/RestServer/DatabaseServerFeature.cpp index a96c1e0925..072b101166 100644 --- a/arangod/RestServer/DatabaseServerFeature.cpp +++ b/arangod/RestServer/DatabaseServerFeature.cpp @@ -82,7 +82,7 @@ void DatabaseServerFeature::start() { } } -void DatabaseServerFeature::stop() { +void DatabaseServerFeature::unprepare() { // turn off index threads INDEX_POOL = nullptr; _indexPool.reset(); diff --git a/arangod/RestServer/DatabaseServerFeature.h b/arangod/RestServer/DatabaseServerFeature.h index dd5f0960fb..51dfa2ce55 100644 --- a/arangod/RestServer/DatabaseServerFeature.h +++ b/arangod/RestServer/DatabaseServerFeature.h @@ -47,7 +47,7 @@ class DatabaseServerFeature final void validateOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; private: uint64_t _indexThreads = 2; diff --git a/arangod/RestServer/QueryRegistryFeature.cpp b/arangod/RestServer/QueryRegistryFeature.cpp index ffd0cf1a3b..ef6efd92c2 100644 --- a/arangod/RestServer/QueryRegistryFeature.cpp +++ b/arangod/RestServer/QueryRegistryFeature.cpp @@ -85,7 +85,7 @@ void QueryRegistryFeature::start() { DatabaseServerFeature::SERVER->_queryRegistry = _queryRegistry.get(); } -void QueryRegistryFeature::stop() { +void QueryRegistryFeature::unprepare() { // clear the query registery DatabaseServerFeature::SERVER->_queryRegistry = nullptr; // TODO: reset QUERY_REGISTRY as well? diff --git a/arangod/RestServer/QueryRegistryFeature.h b/arangod/RestServer/QueryRegistryFeature.h index 25086f0f9e..c6337534c3 100644 --- a/arangod/RestServer/QueryRegistryFeature.h +++ b/arangod/RestServer/QueryRegistryFeature.h @@ -42,7 +42,7 @@ class QueryRegistryFeature final : public application_features::ApplicationFeatu void validateOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; private: bool _queryTracking = true; diff --git a/arangod/RestServer/RestServerFeature.cpp b/arangod/RestServer/RestServerFeature.cpp index 997dc0f88f..b05d7c4b9c 100644 --- a/arangod/RestServer/RestServerFeature.cpp +++ b/arangod/RestServer/RestServerFeature.cpp @@ -315,13 +315,14 @@ void RestServerFeature::stop() { for (auto& server : _servers) { server->stop(); } +} +void RestServerFeature::unprepare() { for (auto& server : _servers) { delete server; } _httpOptions._vocbase = nullptr; - RESTSERVER = nullptr; } diff --git a/arangod/RestServer/RestServerFeature.h b/arangod/RestServer/RestServerFeature.h index 07001fa9b5..e53bca5324 100644 --- a/arangod/RestServer/RestServerFeature.h +++ b/arangod/RestServer/RestServerFeature.h @@ -78,6 +78,7 @@ class RestServerFeature final void prepare() override final; void start() override final; void stop() override final; + void unprepare() override final; private: double _keepAliveTimeout; diff --git a/arangod/Scheduler/SchedulerFeature.cpp b/arangod/Scheduler/SchedulerFeature.cpp index 6dd0aa50f1..43dc75634f 100644 --- a/arangod/Scheduler/SchedulerFeature.cpp +++ b/arangod/Scheduler/SchedulerFeature.cpp @@ -141,8 +141,11 @@ void SchedulerFeature::stop() { } _scheduler->shutdown(); + } +} - // delete the scheduler +void SchedulerFeature::unprepare() { + if (_scheduler != nullptr) { delete _scheduler; _scheduler = nullptr; SCHEDULER = nullptr; diff --git a/arangod/Scheduler/SchedulerFeature.h b/arangod/Scheduler/SchedulerFeature.h index 445b241abf..755fd19445 100644 --- a/arangod/Scheduler/SchedulerFeature.h +++ b/arangod/Scheduler/SchedulerFeature.h @@ -46,6 +46,7 @@ class SchedulerFeature final : public application_features::ApplicationFeature { void validateOptions(std::shared_ptr) override final; void start() override final; void stop() override final; + void unprepare() override final; private: uint64_t _nrSchedulerThreads; diff --git a/arangod/V8Server/V8DealerFeature.cpp b/arangod/V8Server/V8DealerFeature.cpp index 05dbb2e7ec..e186904459 100644 --- a/arangod/V8Server/V8DealerFeature.cpp +++ b/arangod/V8Server/V8DealerFeature.cpp @@ -224,7 +224,7 @@ void V8DealerFeature::start() { startGarbageCollection(); } -void V8DealerFeature::stop() { +void V8DealerFeature::unprepare() { shutdownContexts(); // delete GC thread after all action threads have been stopped diff --git a/arangod/V8Server/V8DealerFeature.h b/arangod/V8Server/V8DealerFeature.h index c467d379d5..ec742a1014 100644 --- a/arangod/V8Server/V8DealerFeature.h +++ b/arangod/V8Server/V8DealerFeature.h @@ -45,7 +45,7 @@ class V8DealerFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; private: double _gcFrequency; diff --git a/arangosh/Benchmark/BenchFeature.cpp b/arangosh/Benchmark/BenchFeature.cpp index 84891e10bf..0faedde84e 100644 --- a/arangosh/Benchmark/BenchFeature.cpp +++ b/arangosh/Benchmark/BenchFeature.cpp @@ -314,6 +314,6 @@ void BenchFeature::start() { *_result = ret; } -void BenchFeature::stop() { +void BenchFeature::unprepare() { ARANGOBENCH = nullptr; } diff --git a/arangosh/Benchmark/BenchFeature.h b/arangosh/Benchmark/BenchFeature.h index 0e0fadeed2..ebd937ce83 100644 --- a/arangosh/Benchmark/BenchFeature.h +++ b/arangosh/Benchmark/BenchFeature.h @@ -32,8 +32,8 @@ class BenchFeature final : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override; - void start() override; - void stop() override; + void start() override final; + void unprepare() override final; public: bool async() const { return _async; } diff --git a/arangosh/Shell/ConsoleFeature.cpp b/arangosh/Shell/ConsoleFeature.cpp index aac58c7392..5172c1acc2 100644 --- a/arangosh/Shell/ConsoleFeature.cpp +++ b/arangosh/Shell/ConsoleFeature.cpp @@ -136,7 +136,7 @@ void ConsoleFeature::start() { #endif } -void ConsoleFeature::stop() { +void ConsoleFeature::unprepare() { closeLog(); } diff --git a/arangosh/Shell/ConsoleFeature.h b/arangosh/Shell/ConsoleFeature.h index f7bdb2f979..9b60bfcf9c 100644 --- a/arangosh/Shell/ConsoleFeature.h +++ b/arangosh/Shell/ConsoleFeature.h @@ -36,7 +36,7 @@ class ConsoleFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; public: bool quiet() const { return _quiet; } diff --git a/arangosh/Shell/V8ShellFeature.cpp b/arangosh/Shell/V8ShellFeature.cpp index edc33e8a66..6a00d561be 100644 --- a/arangosh/Shell/V8ShellFeature.cpp +++ b/arangosh/Shell/V8ShellFeature.cpp @@ -130,7 +130,7 @@ void V8ShellFeature::start() { initGlobals(); } -void V8ShellFeature::stop() { +void V8ShellFeature::unprepare() { { v8::Locker locker{_isolate}; diff --git a/arangosh/Shell/V8ShellFeature.h b/arangosh/Shell/V8ShellFeature.h index 06822d2d41..5be29b574e 100644 --- a/arangosh/Shell/V8ShellFeature.h +++ b/arangosh/Shell/V8ShellFeature.h @@ -44,8 +44,8 @@ class V8ShellFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override; void validateOptions( std::shared_ptr options) override; - void start() override; - void stop() override; + void start() override final; + void unprepare() override final; private: std::string _startupDirectory; diff --git a/js/server/modules/@arangodb/aql.js b/js/server/modules/@arangodb/aql.js index c374f7f485..0dfe22d2a6 100644 --- a/js/server/modules/@arangodb/aql.js +++ b/js/server/modules/@arangodb/aql.js @@ -2301,7 +2301,7 @@ function AQL_LIKE (value, regex, caseInsensitive) { /// @brief searches a substring in a string, using a regex //////////////////////////////////////////////////////////////////////////////// -function AQL_REGEX (value, regex, caseInsensitive) { +function AQL_REGEX_MATCH (value, regex, caseInsensitive) { 'use strict'; var modifiers = ''; @@ -8358,7 +8358,7 @@ exports.AQL_UPPER = AQL_UPPER; exports.AQL_SUBSTRING = AQL_SUBSTRING; exports.AQL_CONTAINS = AQL_CONTAINS; exports.AQL_LIKE = AQL_LIKE; -exports.AQL_REGEX = AQL_REGEX; +exports.AQL_REGEX_MATCH = AQL_REGEX_MATCH; exports.AQL_LEFT = AQL_LEFT; exports.AQL_RIGHT = AQL_RIGHT; exports.AQL_TRIM = AQL_TRIM; diff --git a/js/server/tests/aql/aql-functions-string.js b/js/server/tests/aql/aql-functions-string.js index 95a9c91c01..f529bb16e0 100644 --- a/js/server/tests/aql/aql-functions-string.js +++ b/js/server/tests/aql/aql-functions-string.js @@ -62,18 +62,18 @@ function ahuacatlStringFunctionsTestSuite () { //////////////////////////////////////////////////////////////////////////////// testRegexInvalid : function () { - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX()"); - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX(\"test\")"); - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX(\"test\", \"meow\", \"foo\", \"bar\")"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH()"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH(\"test\")"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH(\"test\", \"meow\", \"foo\", \"bar\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"[\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"[^\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"a.(\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"(a\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"(a]\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"**\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"?\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"*\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"[\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"[^\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"a.(\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"(a\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"(a]\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"**\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"?\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"*\")"); }, testRegex : function () { @@ -217,13 +217,13 @@ function ahuacatlStringFunctionsTestSuite () { ]; values.forEach(function(v) { - var query = "RETURN REGEX(@what, @re)"; + var query = "RETURN REGEX_MATCH(@what, @re)"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); - query = "RETURN NOOPT(REGEX(@what, @re))"; + query = "RETURN NOOPT(REGEX_MATCH(@what, @re))"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); - query = "RETURN NOOPT(V8(REGEX(@what, @re)))"; + query = "RETURN NOOPT(V8(REGEX_MATCH(@what, @re)))"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); }); diff --git a/lib/ApplicationFeatures/ApplicationFeature.cpp b/lib/ApplicationFeatures/ApplicationFeature.cpp index f516cfc427..65773baed5 100644 --- a/lib/ApplicationFeatures/ApplicationFeature.cpp +++ b/lib/ApplicationFeatures/ApplicationFeature.cpp @@ -72,9 +72,12 @@ void ApplicationFeature::start() {} // notify the feature about a shutdown request void ApplicationFeature::beginShutdown() {} -// stop and shut down the feature +// stop the feature void ApplicationFeature::stop() {} +// shut down the feature +void ApplicationFeature::unprepare() {} + // determine all direct and indirect ancestors of a feature std::unordered_set ApplicationFeature::ancestors() const { TRI_ASSERT(_ancestorsDetermined); diff --git a/lib/ApplicationFeatures/ApplicationFeature.h b/lib/ApplicationFeatures/ApplicationFeature.h index 86119b39d9..b590f8a23a 100644 --- a/lib/ApplicationFeatures/ApplicationFeature.h +++ b/lib/ApplicationFeatures/ApplicationFeature.h @@ -126,9 +126,12 @@ class ApplicationFeature { // notify the feature about a shutdown request virtual void beginShutdown(); - // stop and shut down the feature + // stop the feature virtual void stop(); + // shut down the feature + virtual void unprepare(); + protected: // return the ApplicationServer instance ApplicationServer* server() const { return _server; } diff --git a/lib/ApplicationFeatures/ApplicationServer.cpp b/lib/ApplicationFeatures/ApplicationServer.cpp index caf005f932..3eb5ce3b84 100644 --- a/lib/ApplicationFeatures/ApplicationServer.cpp +++ b/lib/ApplicationFeatures/ApplicationServer.cpp @@ -205,6 +205,11 @@ void ApplicationServer::run(int argc, char* argv[]) { reportServerProgress(_state); stop(); + // unprepare all features + _state = ServerState::IN_UNPREPARE; + reportServerProgress(_state); + unprepare(); + // stopped _state = ServerState::STOPPED; reportServerProgress(_state); @@ -540,12 +545,25 @@ void ApplicationServer::stop() { auto feature = *it; LOG_TOPIC(TRACE, Logger::STARTUP) << feature->name() << "::stop"; - feature->stop(); + // feature->stop(); feature->state(FeatureState::STOPPED); reportFeatureProgress(_state, feature->name()); } } +void ApplicationServer::unprepare() { + LOG_TOPIC(TRACE, Logger::STARTUP) << "ApplicationServer::unprepare"; + + for (auto it = _orderedFeatures.rbegin(); it != _orderedFeatures.rend(); ++it) { + auto feature = *it; + + LOG_TOPIC(TRACE, Logger::STARTUP) << feature->name() << "::unprepare"; + feature->unprepare(); + feature->state(FeatureState::UNPREPARED); + reportFeatureProgress(_state, feature->name()); + } +} + void ApplicationServer::wait() { LOG_TOPIC(TRACE, Logger::STARTUP) << "ApplicationServer::wait"; diff --git a/lib/ApplicationFeatures/ApplicationServer.h b/lib/ApplicationFeatures/ApplicationServer.h index aa51f37b3b..65bbe79ce2 100644 --- a/lib/ApplicationFeatures/ApplicationServer.h +++ b/lib/ApplicationFeatures/ApplicationServer.h @@ -44,6 +44,7 @@ enum class ServerState { IN_START, IN_WAIT, IN_STOP, + IN_UNPREPARE, STOPPED, ABORT }; @@ -103,6 +104,11 @@ class ProgressHandler { // `stop` // // Stops the features. The `stop` methods are called in reversed `start` order. +// This must stop all threads, but not destroy the features. +// +// `unprepare` +// +// This destroys the features. class ApplicationServer { ApplicationServer(ApplicationServer const&) = delete; @@ -115,7 +121,8 @@ class ApplicationServer { VALIDATED, PREPARED, STARTED, - STOPPED + STOPPED, + UNPREPARED }; static ApplicationServer* server; @@ -252,6 +259,9 @@ class ApplicationServer { // stops features void stop(); + // destroys features + void unprepare(); + // after start, the server will wait in this method until // beginShutdown is called void wait(); diff --git a/lib/ApplicationFeatures/DaemonFeature.cpp b/lib/ApplicationFeatures/DaemonFeature.cpp index 3114dfc4ef..597539d3f8 100644 --- a/lib/ApplicationFeatures/DaemonFeature.cpp +++ b/lib/ApplicationFeatures/DaemonFeature.cpp @@ -118,7 +118,7 @@ void DaemonFeature::daemonize() { } } -void DaemonFeature::stop() { +void DaemonFeature::unprepare() { if (!_daemon) { return; } diff --git a/lib/ApplicationFeatures/DaemonFeature.h b/lib/ApplicationFeatures/DaemonFeature.h index 0efb0ba1c2..2e300498ad 100644 --- a/lib/ApplicationFeatures/DaemonFeature.h +++ b/lib/ApplicationFeatures/DaemonFeature.h @@ -36,7 +36,7 @@ class DaemonFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void daemonize() override final; - void stop() override final; + void unprepare() override final; public: void setDaemon(bool value) { _daemon = value; } diff --git a/lib/ApplicationFeatures/NonceFeature.cpp b/lib/ApplicationFeatures/NonceFeature.cpp index 8a4cac5fb5..291ca106d4 100644 --- a/lib/ApplicationFeatures/NonceFeature.cpp +++ b/lib/ApplicationFeatures/NonceFeature.cpp @@ -51,10 +51,6 @@ void NonceFeature::prepare() { } } -void NonceFeature::start() { - LOG(DEBUG) << "setting nonce hash size to " << _size; -} - -void NonceFeature::stop() { +void NonceFeature::unprepare() { Nonce::destroy(); } diff --git a/lib/ApplicationFeatures/NonceFeature.h b/lib/ApplicationFeatures/NonceFeature.h index 3ebeed5033..f00763fbda 100644 --- a/lib/ApplicationFeatures/NonceFeature.h +++ b/lib/ApplicationFeatures/NonceFeature.h @@ -36,8 +36,7 @@ class NonceFeature : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override final; void prepare() override final; - void start() override final; - void stop() override final; + void unprepare() override final; private: uint64_t _size; diff --git a/lib/ApplicationFeatures/SupervisorFeature.cpp b/lib/ApplicationFeatures/SupervisorFeature.cpp index 9642d3ab5e..d671ef01bf 100644 --- a/lib/ApplicationFeatures/SupervisorFeature.cpp +++ b/lib/ApplicationFeatures/SupervisorFeature.cpp @@ -33,6 +33,15 @@ using namespace arangodb::application_features; using namespace arangodb::basics; using namespace arangodb::options; +static bool DONE = false; +static int CLIENT_PID = false; + +static void StopHandler(int) { + LOG_TOPIC(INFO, Logger::STARTUP) << "received SIGINT for supervisor"; + kill(CLIENT_PID, SIGTERM); + DONE = true; +} + SupervisorFeature::SupervisorFeature( application_features::ApplicationServer* server) : ApplicationFeature(server, "Supervisor"), _supervisor(false) { @@ -104,11 +113,8 @@ void SupervisorFeature::daemonize() { // parent (supervisor) if (0 < _clientPid) { - LOG_TOPIC(DEBUG, Logger::STARTUP) << "supervisor mode: within parent"; TRI_SetProcessTitle("arangodb [supervisor]"); - ArangoGlobalContext::CONTEXT->unmaskStandardSignals(); - std::for_each(supervisorFeatures.begin(), supervisorFeatures.end(), [](ApplicationFeature* feature) { LoggerFeature* logger = @@ -126,81 +132,98 @@ void SupervisorFeature::daemonize() { std::for_each(supervisorFeatures.begin(), supervisorFeatures.end(), [](ApplicationFeature* feature) { feature->start(); }); + LOG_TOPIC(DEBUG, Logger::STARTUP) << "supervisor mode: within parent"; + + ArangoGlobalContext::CONTEXT->unmaskStandardSignals(); + signal(SIGINT, StopHandler); + signal(SIGTERM, StopHandler); + + CLIENT_PID = _clientPid; + DONE = false; + int status; - waitpid(_clientPid, &status, 0); + int res = waitpid(_clientPid, &status, 0); bool horrible = true; - if (WIFEXITED(status)) { - // give information about cause of death - if (WEXITSTATUS(status) == 0) { - LOG_TOPIC(INFO, Logger::STARTUP) << "child " << _clientPid - << " died of natural causes"; - done = true; - horrible = false; - } else { - t = time(0) - startTime; + if (!DONE) { + done = true; + horrible = false; + } + else { + LOG_TOPIC(DEBUG, Logger::STARTUP) << "waitpid woke up with return value " + << res << " and status " << status; - LOG_TOPIC(ERR, Logger::STARTUP) - << "child " << _clientPid - << " died a horrible death, exit status " << WEXITSTATUS(status); + if (WIFEXITED(status)) { + // give information about cause of death + if (WEXITSTATUS(status) == 0) { + LOG_TOPIC(INFO, Logger::STARTUP) << "child " << _clientPid + << " died of natural causes"; + done = true; + horrible = false; + } else { + t = time(0) - startTime; - if (t < MIN_TIME_ALIVE_IN_SEC) { - LOG_TOPIC(ERR, Logger::STARTUP) - << "child only survived for " << t - << " seconds, this will not work - please fix the error " - "first"; - done = true; - } else { - done = false; - } - } - } else if (WIFSIGNALED(status)) { - switch (WTERMSIG(status)) { - case 2: - case 9: - case 15: - LOG_TOPIC(INFO, Logger::STARTUP) - << "child " << _clientPid - << " died of natural causes, exit status " << WTERMSIG(status); - done = true; - horrible = false; - break; + LOG_TOPIC(ERR, Logger::STARTUP) + << "child " << _clientPid + << " died a horrible death, exit status " << WEXITSTATUS(status); - default: - t = time(0) - startTime; + if (t < MIN_TIME_ALIVE_IN_SEC) { + LOG_TOPIC(ERR, Logger::STARTUP) + << "child only survived for " << t + << " seconds, this will not work - please fix the error " + "first"; + done = true; + } else { + done = false; + } + } + } else if (WIFSIGNALED(status)) { + switch (WTERMSIG(status)) { + case 2: + case 9: + case 15: + LOG_TOPIC(INFO, Logger::STARTUP) + << "child " << _clientPid + << " died of natural causes, exit status " << WTERMSIG(status); + done = true; + horrible = false; + break; - LOG_TOPIC(ERR, Logger::STARTUP) << "child " << _clientPid - << " died a horrible death, signal " - << WTERMSIG(status); + default: + t = time(0) - startTime; - if (t < MIN_TIME_ALIVE_IN_SEC) { - LOG_TOPIC(ERR, Logger::STARTUP) - << "child only survived for " << t - << " seconds, this will not work - please fix the " - "error first"; - done = true; + LOG_TOPIC(ERR, Logger::STARTUP) << "child " << _clientPid + << " died a horrible death, signal " + << WTERMSIG(status); + + if (t < MIN_TIME_ALIVE_IN_SEC) { + LOG_TOPIC(ERR, Logger::STARTUP) + << "child only survived for " << t + << " seconds, this will not work - please fix the " + "error first"; + done = true; #ifdef WCOREDUMP - if (WCOREDUMP(status)) { - LOG_TOPIC(WARN, Logger::STARTUP) << "child process " - << _clientPid - << " produced a core dump"; - } + if (WCOREDUMP(status)) { + LOG_TOPIC(WARN, Logger::STARTUP) << "child process " + << _clientPid + << " produced a core dump"; + } #endif - } else { - done = false; - } + } else { + done = false; + } - break; - } - } else { - LOG_TOPIC(ERR, Logger::STARTUP) - << "child " << _clientPid - << " died a horrible death, unknown cause"; - done = false; + break; + } + } else { + LOG_TOPIC(ERR, Logger::STARTUP) + << "child " << _clientPid + << " died a horrible death, unknown cause"; + done = false; + } } - // remove pid file if (horrible) { result = EXIT_FAILURE; } @@ -223,5 +246,8 @@ void SupervisorFeature::daemonize() { std::for_each(supervisorFeatures.rbegin(), supervisorFeatures.rend(), [](ApplicationFeature* feature) { feature->stop(); }); + std::for_each(supervisorFeatures.rbegin(), supervisorFeatures.rend(), + [](ApplicationFeature* feature) { feature->unprepare(); }); + exit(result); } diff --git a/lib/ApplicationFeatures/V8PlatformFeature.cpp b/lib/ApplicationFeatures/V8PlatformFeature.cpp index 33e717be55..619135659e 100644 --- a/lib/ApplicationFeatures/V8PlatformFeature.cpp +++ b/lib/ApplicationFeatures/V8PlatformFeature.cpp @@ -80,7 +80,7 @@ void V8PlatformFeature::start() { _allocator.reset(new ArrayBufferAllocator); } -void V8PlatformFeature::stop() { +void V8PlatformFeature::unprepare() { v8::V8::Dispose(); v8::V8::ShutdownPlatform(); _platform.reset(); diff --git a/lib/ApplicationFeatures/V8PlatformFeature.h b/lib/ApplicationFeatures/V8PlatformFeature.h index f7da36e46f..c8c2cbb3c0 100644 --- a/lib/ApplicationFeatures/V8PlatformFeature.h +++ b/lib/ApplicationFeatures/V8PlatformFeature.h @@ -37,7 +37,7 @@ class V8PlatformFeature final public: void collectOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; v8::ArrayBuffer::Allocator* arrayBufferAllocator() const { return _allocator.get(); diff --git a/lib/ApplicationFeatures/WorkMonitorFeature.cpp b/lib/ApplicationFeatures/WorkMonitorFeature.cpp index 2af903af94..13c929935c 100644 --- a/lib/ApplicationFeatures/WorkMonitorFeature.cpp +++ b/lib/ApplicationFeatures/WorkMonitorFeature.cpp @@ -35,4 +35,4 @@ WorkMonitorFeature::WorkMonitorFeature( void WorkMonitorFeature::start() { InitializeWorkMonitor(); } -void WorkMonitorFeature::stop() { ShutdownWorkMonitor(); } +void WorkMonitorFeature::unprepare() { ShutdownWorkMonitor(); } diff --git a/lib/ApplicationFeatures/WorkMonitorFeature.h b/lib/ApplicationFeatures/WorkMonitorFeature.h index 2e4266b2f0..d92378c8af 100644 --- a/lib/ApplicationFeatures/WorkMonitorFeature.h +++ b/lib/ApplicationFeatures/WorkMonitorFeature.h @@ -33,7 +33,7 @@ class WorkMonitorFeature final public: void start() override final; - void stop() override final; + void unprepare() override final; }; } diff --git a/lib/Logger/LoggerFeature.cpp b/lib/Logger/LoggerFeature.cpp index 2feb29d9a3..b498b371f5 100644 --- a/lib/Logger/LoggerFeature.cpp +++ b/lib/Logger/LoggerFeature.cpp @@ -177,7 +177,7 @@ void LoggerFeature::prepare() { } } -void LoggerFeature::stop() { +void LoggerFeature::unprepare() { Logger::flush(); Logger::shutdown(true); } diff --git a/lib/Logger/LoggerFeature.h b/lib/Logger/LoggerFeature.h index 5cbc13bbad..ce1e9fe08e 100644 --- a/lib/Logger/LoggerFeature.h +++ b/lib/Logger/LoggerFeature.h @@ -35,7 +35,7 @@ class LoggerFeature final : public application_features::ApplicationFeature { void loadOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void prepare() override final; - void stop() override final; + void unprepare() override final; public: void setBackgrounded(bool backgrounded) { _backgrounded = backgrounded; } diff --git a/lib/Ssl/SslFeature.cpp b/lib/Ssl/SslFeature.cpp index a9821594c3..e2fae73a62 100644 --- a/lib/Ssl/SslFeature.cpp +++ b/lib/Ssl/SslFeature.cpp @@ -145,7 +145,7 @@ void SslFeature::prepare() { opensslSetup(); } -void SslFeature::stop() { +void SslFeature::unprepare() { opensslCleanup(); ERR_free_strings(); diff --git a/lib/Ssl/SslFeature.h b/lib/Ssl/SslFeature.h index 7721ecf60b..1a6acc1d11 100644 --- a/lib/Ssl/SslFeature.h +++ b/lib/Ssl/SslFeature.h @@ -34,7 +34,7 @@ class SslFeature final : public application_features::ApplicationFeature { public: void prepare() override final; - void stop() override final; + void unprepare() override final; }; } diff --git a/lib/Ssl/SslServerFeature.cpp b/lib/Ssl/SslServerFeature.cpp index 89d939c500..27f5fc69a1 100644 --- a/lib/Ssl/SslServerFeature.cpp +++ b/lib/Ssl/SslServerFeature.cpp @@ -94,9 +94,7 @@ void SslServerFeature::collectOptions(std::shared_ptr options) { void SslServerFeature::prepare() { createSslContext(); -} -void SslServerFeature::start() { LOG(INFO) << "using SSL options: " << stringifySslOptions(_options); if (!_cipherList.empty()) { @@ -104,7 +102,7 @@ void SslServerFeature::start() { } } -void SslServerFeature::stop() { +void SslServerFeature::unprepare() { if (_sslContext != nullptr) { SSL_CTX_free(_sslContext); _sslContext = nullptr; diff --git a/lib/Ssl/SslServerFeature.h b/lib/Ssl/SslServerFeature.h index 03cc5ba577..7c35c196ea 100644 --- a/lib/Ssl/SslServerFeature.h +++ b/lib/Ssl/SslServerFeature.h @@ -35,8 +35,7 @@ class SslServerFeature final : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override final; void prepare() override final; - void start() override final; - void stop() override final; + void unprepare() override final; public: SSL_CTX* sslContext() const { return _sslContext; }