Class: Riser::RootProcess
- Inherits:
-
Object
- Object
- Riser::RootProcess
- Includes:
- ServerSignal
- Defined in:
- lib/riser/daemon.rb
Defined Under Namespace
Classes: SystemOperation
Constant Summary
Constants included from ServerSignal
ServerSignal::SIGNAL_RESTART_FORCED, ServerSignal::SIGNAL_RESTART_GRACEFUL, ServerSignal::SIGNAL_STAT_GET_AND_RESET, ServerSignal::SIGNAL_STAT_GET_NO_RESET, ServerSignal::SIGNAL_STAT_STOP, ServerSignal::SIGNAL_STOP_FORCED, ServerSignal::SIGNAL_STOP_GRACEFUL
Instance Method Summary collapse
-
#initialize(logger, sockaddr_get, server_polling_interval_seconds, server_restart_overlap_seconds = 0, euid = nil, egid = nil, &block) ⇒ RootProcess
constructor
:yields: socket_server.
-
#signal_restart_forced ⇒ Object
should be called from signal(2) handler.
-
#signal_restart_graceful ⇒ Object
should be called from signal(2) handler.
-
#signal_server_down ⇒ Object
should be called from signal(2) handler.
-
#signal_stat_get(reset: true) ⇒ Object
should be called from signal(2) handler.
-
#signal_stat_stop ⇒ Object
should be called from signal(2) handler.
-
#signal_stop_forced ⇒ Object
should be called from signal(2) handler.
-
#signal_stop_graceful ⇒ Object
should be called from signal(2) handler.
-
#start ⇒ Object
should be executed on the main thread sharing the stack with signal(2) handlers.
Constructor Details
#initialize(logger, sockaddr_get, server_polling_interval_seconds, server_restart_overlap_seconds = 0, euid = nil, egid = nil, &block) ⇒ RootProcess
:yields: socket_server
177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/riser/daemon.rb', line 177 def initialize(logger, sockaddr_get, server_polling_interval_seconds, server_restart_overlap_seconds=0, euid=nil, egid=nil, &block) # :yields: socket_server @logger = logger @sockaddr_get = sockaddr_get @server_polling_interval_seconds = server_polling_interval_seconds @server_restart_overlap_seconds = server_restart_overlap_seconds @euid = euid @egid = egid @server_setup = block @sysop = SystemOperation.new(@logger) @stop_state = nil @in_server_polling_sleep = false @signal_operation_queue = [] @process_wait_count_table = {} end |
Instance Method Details
#signal_restart_forced ⇒ Object
should be called from signal(2) handler
233 234 235 236 237 |
# File 'lib/riser/daemon.rb', line 233 def signal_restart_forced @signal_operation_queue << :restart_forced interrupt_server_polling_sleep nil end |
#signal_restart_graceful ⇒ Object
should be called from signal(2) handler
226 227 228 229 230 |
# File 'lib/riser/daemon.rb', line 226 def signal_restart_graceful @signal_operation_queue << :restart_graceful interrupt_server_polling_sleep nil end |
#signal_server_down ⇒ Object
should be called from signal(2) handler
258 259 260 261 |
# File 'lib/riser/daemon.rb', line 258 def signal_server_down interrupt_server_polling_sleep nil end |
#signal_stat_get(reset: true) ⇒ Object
should be called from signal(2) handler
240 241 242 243 244 245 246 247 248 |
# File 'lib/riser/daemon.rb', line 240 def signal_stat_get(reset: true) if (reset) then @signal_operation_queue << :stat_get_and_reset else @signal_operation_queue << :stat_get_no_reset end interrupt_server_polling_sleep nil end |
#signal_stat_stop ⇒ Object
should be called from signal(2) handler
251 252 253 254 255 |
# File 'lib/riser/daemon.rb', line 251 def signal_stat_stop @signal_operation_queue << :stat_stop interrupt_server_polling_sleep nil end |
#signal_stop_forced ⇒ Object
should be called from signal(2) handler
219 220 221 222 223 |
# File 'lib/riser/daemon.rb', line 219 def signal_stop_forced @stop_state ||= :forced interrupt_server_polling_sleep nil end |
#signal_stop_graceful ⇒ Object
should be called from signal(2) handler
212 213 214 215 216 |
# File 'lib/riser/daemon.rb', line 212 def signal_stop_graceful @stop_state ||= :graceful interrupt_server_polling_sleep nil end |
#start ⇒ Object
should be executed on the main thread sharing the stack with signal(2) handlers
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 |
# File 'lib/riser/daemon.rb', line 345 def start @logger.info('daemon start.') unless (server_address = @sysop.get_server_address(@sockaddr_get)) then @logger.fatal('failed to start daemon.') return 1 end unless (server_socket = @sysop.get_server_socket(server_address)) then @logger.fatal('failed to start daemon.') return 1 end @logger.info("open server socket: #{server_socket.local_address.inspect_sockaddr}") begin if (server_address.backlog) then if (@sysop.listen(server_socket, server_address.backlog)) then @logger.info("server socket backlog: #{server_address.backlog}") else @logger.warn('server socket backlog is not changed.') end else @logger.info('server socket backlog is default.') end if (server_address.type == :unix) then if (server_address.mode) then if (@sysop.chmod(server_address.mode, server_address.path)) then @logger.info("unix domain server socket mode: #{'%04o' % server_address.mode}") else @logger.warn('unix domain server socket mode is not changed.') end else @logger.info('unix domain server socket mode is default.') end if (server_address.owner || server_address.group) then if (@sysop.chown(server_address.owner, server_address.group, server_address.path)) then @logger.info("unix domain server socket ownership: <#{server_address.owner}> <#{server_address.group}>") else @logger.warn('unix domain server socket ownership is not changed.') end else @logger.info('unix domain server socket ownership is default.') end end unless (server_pid = run_server(server_socket)) then @logger.fatal('failed to start daemon.') return 1 end @logger.info("server process start (pid: #{server_pid})") @logger.info("start server polling (interval seconds: #{@server_polling_interval_seconds})") until (@stop_state) server_polling_sleep if (server_pid) then @logger.debug("server polling... (pid: #{server_pid})") if @logger.debug? else @logger.debug('server polling...') if @logger.debug? end if (! server_pid || @sysop.wait(server_pid, Process::WNOHANG)) then if (server_pid) then @logger.warn("found server down (pid: #{server_pid}) and restart server.") else @logger.warn('found server down and restart server.') end if (server_pid = run_server(server_socket)) then @logger.info("server process start (pid: #{server_pid})") end end while (! @stop_state && server_pid && sig_ope = @signal_operation_queue.shift) case (sig_ope) when :restart_graceful, :restart_forced if (next_server_address = @sysop.get_server_address(@sockaddr_get)) then if (next_server_address.to_address == server_address.to_address) then if (next_server_address.to_option != server_address.to_option) then server_address = next_server_address end else if (next_server_socket = @sysop.get_server_socket(next_server_address)) then @logger.info("open server socket: #{next_server_socket.local_address.inspect_sockaddr}") server_socket_local_address = server_socket.local_address # get local_address before close(2) if (@sysop.close(server_socket)) then @logger.info("close server socket: #{server_socket_local_address.inspect_sockaddr}") else @logger.warn("failed to close server socket: #{server_socket_local_address.inspect_sockaddr}") end if (server_address.type == :unix) then if (@sysop.unlink(server_address.path)) then @logger.info("delete unix server socket: #{server_address}") else @logger.warn("failed to delete unix server socket: #{server_address}") end end server_socket = next_server_socket server_address = next_server_address else @logger.warn("server socket continue: #{server_socket.local_address.inspect_sockaddr}") end end else @logger.warn("server socket continue: #{server_socket.local_address.inspect_sockaddr}") end if (server_address.backlog) then if (@sysop.listen(server_socket, server_address.backlog)) then @logger.info("server socket backlog: #{server_address.backlog}") else @logger.warn('server socket backlog is not changed.') end else @logger.info('server socket backlog is default.') end if (server_address.type == :unix) then if (server_address.mode) then if (@sysop.chmod(server_address.mode, server_address.path)) then @logger.info("unix domain server socket mode: #{'%04o' % server_address.mode}") else @logger.warn('unix domain server socket mode is not changed.') end else @logger.info('unix domain server socket mode is default.') end if (server_address.owner || server_address.group) then if (@sysop.chown(server_address.owner, server_address.group, server_address.path)) then @logger.info("unix domain server socket ownership: <#{server_address.owner}> <#{server_address.group}>") else @logger.warn('unix domain server socket ownership is not changed.') end else @logger.info('unix domain server socket ownership is default.') end end case (sig_ope) when :restart_graceful @logger.info("server graceful restart (pid: #{server_pid})") when :restart_forced @logger.info("server forced restart (pid: #{server_pid})") else @logger.warn("internal warning: unknown signal operation <#{sig_ope.inspect}>") end if (next_pid = run_server(server_socket)) then @logger.info("server process start (pid: #{next_pid})") if (@server_restart_overlap_seconds > 0) then @logger.info("server restart overlap (interval seconds: #{@server_restart_overlap_seconds})") sleep(@server_restart_overlap_seconds) end case (sig_ope) when :restart_graceful @logger.info("server graceful stop (pid: #{server_pid})") server_stop_graceful(server_pid) when :restart_forced @logger.info("server forced stop (pid: #{server_pid})") server_stop_forced(server_pid) else @logger.warn("internal warning: unknown signal operation <#{sig_ope.inspect}>") end @process_wait_count_table[server_pid] = 0 server_pid = next_pid else @logger.warn("server continue (pid: #{server_pid})") end when :stat_get_and_reset if (@sysop.send_signal(server_pid, SIGNAL_STAT_GET_AND_RESET)) then @logger.info("stat get(reset: true) (pid: #{server_pid})") else @logger.error("failed to stat get(reset: true) (pid: #{server_pid})") end when :stat_get_no_reset if (@sysop.send_signal(server_pid, SIGNAL_STAT_GET_NO_RESET)) then @logger.info("stat get(reset: false) (pid: #{server_pid})") else @logger.error("failed to stat get(reset: false) (pid: #{server_pid})") end when :stat_stop if (@sysop.send_signal(server_pid, SIGNAL_STAT_STOP)) then @logger.info("stat stop (pid: #{server_pid})") else @logger.error("failed to stat stop (pid: #{server_pid})") end else @logger.warn("internal warning: unknown signal operation <#{sig_ope.inspect}>") end end for pid in @process_wait_count_table.keys if (@sysop.wait(pid, Process::WNOHANG)) then @logger.info("server stop completed (pid: #{pid})") @process_wait_count_table.delete(pid) else @process_wait_count_table[pid] += 1 if (@process_wait_count_table[pid] >= 2) then @logger.warn("not stopped server process (pid: #{pid})") end end end end if (server_pid) then case (@stop_state) when :graceful @logger.info("server graceful stop (pid: #{server_pid})") unless (server_stop_graceful(server_pid)) then @logger.fatal('failed to stop daemon.') return 1 end unless (@sysop.wait(server_pid)) then @logger.fatal('failed to stop daemon.') return 1 end when :forced @logger.info("server forced stop (pid: #{server_pid})") unless (server_stop_forced(server_pid)) then @logger.fatal('failed to stop daemon.') return 1 end unless (@sysop.wait(server_pid)) then @logger.fatal('failed to stop daemon.') return 1 end else @logger.warn("internal warning: unknown stop state <#{@stop_state.inspect}>") end else @logger.warn('no server to stop.') end ensure server_socket_local_address = server_socket.local_address # get local_address before close(2) if (@sysop.close(server_socket)) then @logger.info("close server socket: #{server_socket_local_address.inspect_sockaddr}") else @logger.warn("failed to close server socket: #{server_socket_local_address.inspect_sockaddr}") end if (server_address.type == :unix) then if (@sysop.unlink(server_address.path)) then @logger.info("delete unix server socket: #{server_address}") else @logger.warn("failed to delete unix server socket: #{server_address}") end end end @logger.info('daemon stop.') return 0 end |