Skip to content

Commit c05ae0b

Browse files
committed
fix(main): 解决设置了pid_file后还能同时运行多个进程的问题
1 parent 5cc0a88 commit c05ae0b

File tree

2 files changed

+129
-134
lines changed

2 files changed

+129
-134
lines changed

modules/main/run_in_backend.cpp

Lines changed: 114 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <tbox/event/signal_event.h>
2929
#include <tbox/eventx/loop_wdog.h>
3030
#include <tbox/util/pid_file.h>
31+
#include <tbox/util/json.h>
3132

3233
#include "module.h"
3334
#include "context_imp.h"
@@ -49,163 +50,160 @@ extern std::function<void()> error_exit_func;
4950

5051
namespace {
5152
struct Runtime {
52-
Log log;
53-
ContextImp ctx;
54-
Module apps;
55-
int loop_exit_wait = 1;
56-
std::thread thread;
57-
58-
Runtime() : apps("", ctx) {
59-
RegisterApps(apps, ctx);
60-
}
53+
Log log;
54+
ContextImp ctx;
55+
Module apps;
56+
57+
util::PidFile pid_file;
58+
int loop_exit_wait = 1;
59+
bool error_exit_wait = false;
60+
std::thread thread;
61+
62+
Runtime() : apps("", ctx) {
63+
RegisterApps(apps, ctx);
64+
}
6165
};
6266

6367
Runtime* _runtime = nullptr;
6468

6569
void RunInBackend()
6670
{
67-
auto loop = _runtime->ctx.loop();
71+
auto loop = _runtime->ctx.loop();
6872

69-
auto warn_signal = loop->newSignalEvent("main::RunInBackend::warn_signal");
70-
SetScopeExitAction([=] { delete warn_signal; });
73+
auto warn_signal = loop->newSignalEvent("main::RunInBackend::warn_signal");
74+
SetScopeExitAction([=] { delete warn_signal; });
7175

72-
warn_signal->initialize({SIGPIPE, SIGHUP}, event::Event::Mode::kPersist);
73-
warn_signal->setCallback([](int signo) { LogWarn("Got signal %d", signo); });
76+
warn_signal->initialize({SIGPIPE, SIGHUP}, event::Event::Mode::kPersist);
77+
warn_signal->setCallback([](int signo) { LogWarn("Got signal %d", signo); });
7478

75-
//! 启动前准备
76-
eventx::LoopWDog::Start();
77-
eventx::LoopWDog::Register(loop, "main");
79+
//! 启动前准备
80+
eventx::LoopWDog::Start();
81+
eventx::LoopWDog::Register(loop, "main");
7882

79-
warn_signal->enable();
83+
warn_signal->enable();
8084

81-
LogDbg("Start!");
82-
loop->runLoop();
83-
LogDbg("Stoped");
85+
LogDbg("Start!");
86+
loop->runLoop();
87+
LogDbg("Stoped");
8488

85-
eventx::LoopWDog::Unregister(loop);
86-
eventx::LoopWDog::Stop();
89+
eventx::LoopWDog::Unregister(loop);
90+
eventx::LoopWDog::Stop();
8791
}
8892

8993
void End()
9094
{
91-
LogInfo("Bye!");
95+
LogInfo("Bye!");
9296

93-
LogOutput_Enable();
94-
_runtime->log.cleanup();
97+
LogOutput_Enable();
98+
_runtime->log.cleanup();
9599

96-
CHECK_DELETE_RESET_OBJ(_runtime);
100+
CHECK_DELETE_RESET_OBJ(_runtime);
97101

98-
UninstallErrorSignals();
102+
UninstallErrorSignals();
99103
}
100104

101105
}
102106

103-
bool Start(int argc, char **argv) {
104-
if (_runtime != nullptr) {
105-
std::cerr << "Err: process started" << std::endl;
106-
return false;
107-
}
107+
bool Start(int argc, char **argv)
108+
{
109+
if (_runtime != nullptr) {
110+
std::cerr << "Err: process started" << std::endl;
111+
return false;
112+
}
108113

109-
LogOutput_Enable();
114+
LogOutput_Enable();
110115

111-
InstallErrorSignals();
112-
InstallTerminate();
116+
InstallErrorSignals();
117+
InstallTerminate();
113118

114-
_runtime = new Runtime;
119+
_runtime = new Runtime;
115120

116-
auto &log = _runtime->log;
117-
auto &ctx = _runtime->ctx;
118-
auto &apps = _runtime->apps;
121+
auto &log = _runtime->log;
122+
auto &ctx = _runtime->ctx;
123+
auto &apps = _runtime->apps;
119124

120-
Json js_conf;
121-
Args args(js_conf);
125+
Json js_conf;
126+
Args args(js_conf);
122127

123-
log.fillDefaultConfig(js_conf);
124-
ctx.fillDefaultConfig(js_conf);
125-
apps.fillDefaultConfig(js_conf);
128+
log.fillDefaultConfig(js_conf);
129+
ctx.fillDefaultConfig(js_conf);
130+
apps.fillDefaultConfig(js_conf);
126131

127-
if (!args.parse(argc, argv))
128-
return false;
132+
if (!args.parse(argc, argv))
133+
return false;
129134

130-
util::PidFile pid_file;
131-
if (js_conf.contains("pid_file")) {
132-
auto &js_pidfile = js_conf["pid_file"];
133-
if (js_pidfile.is_string()) {
134-
auto pid_filename = js_pidfile.get<std::string>();
135-
if (!pid_filename.empty()) {
136-
if (!pid_file.lock(js_pidfile.get<std::string>())) {
137-
std::cerr << "Warn: another process is running, exit" << std::endl;
138-
return false;
135+
std::string pid_filename;
136+
util::json::GetField(js_conf, "pid_file", pid_filename);
137+
if (!pid_filename.empty()) {
138+
if (!_runtime->pid_file.lock(pid_filename)) {
139+
std::cerr << "Warn: another process is running, exit" << std::endl;
140+
return false;
139141
}
140-
}
141142
}
142-
}
143143

144-
if (js_conf.contains("loop_exit_wait")) {
145-
auto js_loop_exit_wait = js_conf.at("loop_exit_wait");
146-
if (js_loop_exit_wait.is_number()) {
147-
_runtime->loop_exit_wait = js_loop_exit_wait.get<int>();
148-
} else {
149-
std::cerr << "Warn: loop_exit_wait invaild" << std::endl;
150-
}
151-
}
152-
153-
log.initialize(argv[0], ctx, js_conf);
154-
LogOutput_Disable();
155-
156-
SayHello();
157-
158-
error_exit_func = [&] {
159-
log.cleanup();
160-
};
161-
162-
if (ctx.initialize(js_conf)) {
163-
if (apps.initialize(js_conf)) {
164-
if (ctx.start()) { //! 启动所有应用
165-
if (apps.start()) {
166-
_runtime->thread = std::thread(RunInBackend);
167-
return true;
144+
util::json::GetField(js_conf, "loop_exit_wait", _runtime->loop_exit_wait);
145+
util::json::GetField(js_conf, "error_exit_wait", _runtime->error_exit_wait);
146+
147+
log.initialize(argv[0], ctx, js_conf);
148+
LogOutput_Disable();
149+
150+
SayHello();
151+
152+
error_exit_func = [&] {
153+
log.cleanup();
154+
155+
while (_runtime->error_exit_wait)
156+
std::this_thread::sleep_for(std::chrono::seconds(1));
157+
};
158+
159+
if (ctx.initialize(js_conf)) {
160+
if (apps.initialize(js_conf)) {
161+
if (ctx.start()) { //! 启动所有应用
162+
if (apps.start()) {
163+
_runtime->thread = std::thread(RunInBackend);
164+
return true;
165+
} else {
166+
LogErr("App start fail");
167+
}
168+
ctx.stop();
169+
} else {
170+
LogErr("Ctx start fail");
171+
}
172+
apps.cleanup();
168173
} else {
169-
LogErr("App start fail");
174+
LogErr("Apps init fail");
170175
}
171-
ctx.stop();
172-
} else {
173-
LogErr("Ctx start fail");
174-
}
175-
apps.cleanup();
176+
ctx.cleanup();
176177
} else {
177-
LogErr("Apps init fail");
178+
LogErr("Context init fail");
178179
}
179-
ctx.cleanup();
180-
} else {
181-
LogErr("Context init fail");
182-
}
183180

184-
End();
185-
return false;
181+
End();
182+
return false;
186183
}
187184

188-
void Stop() {
189-
if (_runtime == nullptr) {
190-
std::cerr << "Err: process not start" << std::endl;
191-
return;
192-
}
193-
194-
_runtime->ctx.loop()->runInLoop(
195-
[] {
196-
_runtime->apps.stop();
197-
_runtime->ctx.stop();
198-
_runtime->ctx.loop()->exitLoop(std::chrono::seconds(_runtime->loop_exit_wait));
199-
LogDbg("Loop will exit after %d sec", _runtime->loop_exit_wait);
200-
},
201-
"main::Stop"
202-
);
203-
_runtime->thread.join();
204-
205-
_runtime->apps.cleanup(); //! cleanup所有应用
206-
_runtime->ctx.cleanup();
207-
208-
End();
185+
void Stop()
186+
{
187+
if (_runtime == nullptr) {
188+
std::cerr << "Err: process not start" << std::endl;
189+
return;
190+
}
191+
192+
_runtime->ctx.loop()->runInLoop(
193+
[] {
194+
_runtime->apps.stop();
195+
_runtime->ctx.stop();
196+
_runtime->ctx.loop()->exitLoop(std::chrono::seconds(_runtime->loop_exit_wait));
197+
LogDbg("Loop will exit after %d sec", _runtime->loop_exit_wait);
198+
},
199+
"main::Stop"
200+
);
201+
_runtime->thread.join();
202+
203+
_runtime->apps.cleanup(); //! cleanup所有应用
204+
_runtime->ctx.cleanup();
205+
206+
End();
209207
}
210208

211209
}

modules/main/run_in_frontend.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* of the source tree.
1919
*/
2020
#include <iostream>
21+
#include <thread>
2122

2223
#include <tbox/base/log.h>
2324
#include <tbox/base/scope_exit.hpp>
@@ -27,6 +28,7 @@
2728
#include <tbox/event/signal_event.h>
2829
#include <tbox/eventx/loop_wdog.h>
2930
#include <tbox/util/pid_file.h>
31+
#include <tbox/util/json.h>
3032

3133
#include "module.h"
3234
#include "context_imp.h"
@@ -114,29 +116,21 @@ int Main(int argc, char **argv)
114116
if (!args.parse(argc, argv))
115117
return 0;
116118

119+
std::string pid_filename;
117120
util::PidFile pid_file;
118-
if (js_conf.contains("pid_file")) {
119-
auto &js_pidfile = js_conf["pid_file"];
120-
if (js_pidfile.is_string()) {
121-
auto pid_filename = js_pidfile.get<std::string>();
122-
if (!pid_filename.empty()) {
123-
if (!pid_file.lock(js_pidfile.get<std::string>())) {
124-
std::cerr << "Warn: another process is running, exit" << std::endl;
125-
return 0;
126-
}
127-
}
121+
util::json::GetField(js_conf, "pid_file", pid_filename);
122+
if (!pid_filename.empty()) {
123+
if (!pid_file.lock(pid_filename)) {
124+
std::cerr << "Warn: another process is running, exit" << std::endl;
125+
return false;
128126
}
129127
}
130128

131129
int loop_exit_wait = 1;
132-
if (js_conf.contains("loop_exit_wait")) {
133-
auto js_loop_exit_wait = js_conf.at("loop_exit_wait");
134-
if (js_loop_exit_wait.is_number()) {
135-
loop_exit_wait = js_loop_exit_wait.get<int>();
136-
} else {
137-
std::cerr << "Warn: loop_exit_wait invaild" << std::endl;
138-
}
139-
}
130+
util::json::GetField(js_conf, "loop_exit_wait", loop_exit_wait);
131+
132+
bool error_exit_wait = false;
133+
util::json::GetField(js_conf, "error_exit_wait", error_exit_wait);
140134

141135
log.initialize(argv[0], ctx, js_conf);
142136
LogOutput_Disable();
@@ -147,6 +141,9 @@ int Main(int argc, char **argv)
147141
error_exit_func = [&] {
148142
//! 主要是保存日志
149143
log.cleanup();
144+
145+
while (error_exit_wait)
146+
std::this_thread::sleep_for(std::chrono::seconds(1));
150147
};
151148

152149
if (ctx.initialize(js_conf)) {

0 commit comments

Comments
 (0)