1# frozen_string_literal: true 2 3module Gitlab 4 module HealthChecks 5 # This check is registered on master, 6 # and validated by worker 7 class MasterCheck 8 extend SimpleAbstractCheck 9 10 class << self 11 extend ::Gitlab::Utils::Override 12 13 override :available? 14 def available? 15 Gitlab::Runtime.puma_in_clustered_mode? 16 end 17 18 def register_master 19 return unless available? 20 21 # when we fork, we pass the read pipe to child 22 # child can then react on whether the other end 23 # of pipe is still available 24 @pipe_read, @pipe_write = IO.pipe 25 end 26 27 def finish_master 28 return unless available? 29 30 close_read 31 close_write 32 end 33 34 def register_worker 35 return unless available? 36 37 # fork needs to close the pipe 38 close_write 39 end 40 41 private 42 43 def close_read 44 @pipe_read&.close 45 @pipe_read = nil 46 end 47 48 def close_write 49 @pipe_write&.close 50 @pipe_write = nil 51 end 52 53 def metric_prefix 54 'master_check' 55 end 56 57 def successful?(result) 58 result 59 end 60 61 def check 62 # the lack of pipe is a legitimate failure of check 63 return false unless @pipe_read 64 65 @pipe_read.read_nonblock(1) 66 67 true 68 rescue IO::EAGAINWaitReadable 69 # if it is blocked, it means that the pipe is still open 70 # and there's no data waiting on it 71 true 72 rescue EOFError 73 # the pipe is closed 74 false 75 end 76 end 77 end 78 end 79end 80