@@ -101,8 +101,16 @@ Server::Server(engine::Storage *storage, Config *config)
101101 // init shard pub/sub channels
102102 pubsub_shard_channels_.resize (config->cluster_enabled ? HASH_SLOTS_SIZE : 1 );
103103
104+ std::vector<int > listen_fds;
104105 for (int i = 0 ; i < config->workers ; i++) {
105- auto worker = std::make_unique<Worker>(this , config);
106+ #ifdef __APPLE__
107+ auto worker = std::make_unique<Worker>(this , config, listen_fds);
108+ if (i == 0 ) {
109+ listen_fds = worker->GetTCPListenFDs ();
110+ }
111+ #else
112+ auto worker = std::make_unique<Worker>(this , config, std::vector<int >{});
113+ #endif
106114 // multiple workers can't listen to the same unix socket, so
107115 // listen unix socket only from a single worker - the first one
108116 if (!config->unixsocket .empty () && i == 0 ) {
@@ -255,6 +263,13 @@ void Server::Stop() {
255263 if (replication_thread_) replication_thread_->Stop ();
256264 slaveof_mu_.unlock ();
257265
266+ {
267+ std::lock_guard<std::mutex> guard (running_scripts_mu_);
268+ for (auto *rctx : running_scripts_) {
269+ rctx->is_killed = true ;
270+ }
271+ }
272+
258273 for (const auto &worker : worker_threads_) {
259274 worker->Stop (0 /* immediately terminate */ );
260275 }
@@ -1879,6 +1894,62 @@ StatusOr<std::unique_ptr<redis::Commander>> Server::LookupAndCreateCommand(const
18791894 return std::move (cmd);
18801895}
18811896
1897+ void Server::RegisterRunningScript (lua::ScriptRunCtx *rctx) {
1898+ std::lock_guard<std::mutex> guard (running_scripts_mu_);
1899+ running_scripts_.push_back (rctx);
1900+ }
1901+
1902+ void Server::UnregisterRunningScript (lua::ScriptRunCtx *rctx) {
1903+ std::lock_guard<std::mutex> guard (running_scripts_mu_);
1904+ auto it = std::find (running_scripts_.begin (), running_scripts_.end (), rctx);
1905+ if (it != running_scripts_.end ()) {
1906+ running_scripts_.erase (it);
1907+ }
1908+
1909+ // Re-evaluate if any remaining scripts are timed out, if not, clear the flag
1910+ bool any_timed_out = false ;
1911+ int limit = config_->lua_time_limit ;
1912+ if (limit > 0 && !running_scripts_.empty ()) {
1913+ uint64_t now_ms = util::GetTimeStampMS ();
1914+ for (const auto *ctx : running_scripts_) {
1915+ if (now_ms - ctx->start_time_ms >= static_cast <uint64_t >(limit)) {
1916+ any_timed_out = true ;
1917+ break ;
1918+ }
1919+ }
1920+ }
1921+ is_script_timeout_.store (any_timed_out, std::memory_order_relaxed);
1922+ }
1923+
1924+ bool Server::IsScriptTimedOut () const { return is_script_timeout_.load (std::memory_order_relaxed); }
1925+
1926+ void Server::SetScriptTimedOut (bool timed_out) { is_script_timeout_.store (timed_out, std::memory_order_relaxed); }
1927+
1928+ Status Server::ScriptKill () {
1929+ std::lock_guard<std::mutex> guard (running_scripts_mu_);
1930+ if (running_scripts_.empty ()) {
1931+ return {Status::NotOK, " NOTBUSY No scripts in execution right now." };
1932+ }
1933+
1934+ bool has_unkillable = false ;
1935+ for (auto *rctx : running_scripts_) {
1936+ if (rctx->is_write_dirty ) {
1937+ has_unkillable = true ;
1938+ } else {
1939+ rctx->is_killed = true ;
1940+ }
1941+ }
1942+
1943+ if (has_unkillable) {
1944+ return {Status::NotOK,
1945+ " UNKILLABLE Sorry the script already executed write commands against the dataset. "
1946+ " You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE "
1947+ " command." };
1948+ }
1949+
1950+ return Status::OK ();
1951+ }
1952+
18821953Status Server::ScriptExists (const std::string &sha) const {
18831954 std::string body;
18841955 return ScriptGet (sha, &body);
@@ -2068,8 +2139,14 @@ void Server::AdjustWorkerThreads() {
20682139}
20692140
20702141void Server::increaseWorkerThreads (size_t delta) {
2142+ std::vector<int > listen_fds;
2143+ #ifdef __APPLE__
2144+ if (!worker_threads_.empty ()) {
2145+ listen_fds = worker_threads_[0 ]->GetWorker ()->GetTCPListenFDs ();
2146+ }
2147+ #endif
20712148 for (size_t i = 0 ; i < delta; i++) {
2072- auto worker = std::make_unique<Worker>(this , config_);
2149+ auto worker = std::make_unique<Worker>(this , config_, listen_fds );
20732150 auto worker_thread = std::make_unique<WorkerThread>(std::move (worker));
20742151 worker_thread->Start ();
20752152 worker_threads_.emplace_back (std::move (worker_thread));
0 commit comments