
рдЖрдЬ, рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕реВрдЪрдирд╛ рдкреНрд░рдгрд╛рд▓реА рдПрдХ рдЬрдЯрд┐рд▓ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рдЬрдЯрд┐рд▓ рд╕рдорд╛рдзрд╛рди рдФрд░ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкрд╛рд░рд╕реНрдкрд░рд┐рдХ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВред рдРрд╕реА рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рджреМрд░рд╛рди, рдкреАрдХ рд▓реЛрдб рдХреЗ рд╕рдордп, рдХреБрдЫ рдореЙрдбреНрдпреВрд▓ рд╡рд┐рдлрд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╕рд┐рд╕реНрдЯрдо рд╕реНрдерд┐рд░ рд╣реЛрдирд╛ рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдВрдж рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕реНрдерд┐рд░ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд┐рднрд┐рдиреНрди рд░рдгрдиреАрддрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ (рдпрджрд┐ рдпрд╣ рдЕрдиреБрдореЗрдп рд╣реИ), рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рддрдерд╛рдХрдерд┐рдд рдореЗрдВ рдЕрдиреБрд╡рд╛рджред "рд╕реБрд░рдХреНрд╖рд┐рдд рдореЛрдб"ред рдЗрд╕ рдореЛрдб рдореЗрдВ, рд╕рд┐рд╕реНрдЯрдо рдХреНрд╡реЗрд░реА рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рд╕рдЯреАрдХрддрд╛ рдореЗрдВ рдереЛрдбрд╝реА рдЧрд┐рд░рд╛рд╡рдЯ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рдХреЙрд▓ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдФрд░ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╕рд┐рд╕реНрдЯрдо рдореЙрдбреНрдпреВрд▓ рдХреА рд╕рдВрдЦреНрдпрд╛ рдмрдврд╝рд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд╛рд░реНрдп
рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ
рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реИ , рдЬрд┐рд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЗрд╕рдХреЗ рдХрд╛рдо рдХреЛ рд╕реНрдерд┐рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред
рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ, рдореИрдВ рдХрд╛рдлреА рд╕рдордп рд╕реЗ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рд╕реЗ рдЗрд╕реА рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЬрдм рд╕реЗ рдореИрдВ рд╡рд┐рд╢реНрд╡рд╡рд┐рджреНрдпрд╛рд▓рдп рдореЗрдВ рдерд╛, рдореЗрд░реЗ рдкрд╛рд╕ .NET 4.0 рдореЗрдВ рд▓рд┐рдЦрд╛ рдПрдХ рдЫреЛрдЯрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдерд╛, рдЬрд┐рд╕рдореЗрдВ рд╕рдордп-рд╕рдордп рдкрд░ рдореИрдВрдиреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдЫреЛрдЯреЗ-рдЫреЛрдЯреЗ рдХреЛрдб рдХреЛрдб рд▓рд┐рдПред рдореИрдВрдиреЗ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд░рдиреЗ, рдЗрд╕реЗ рд╕рд╛рдл рдХрд░рдиреЗ рдФрд░ рдПрдХ рдЕрд▓рдЧ рдорд┐рдиреА-рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ рдФрд░ рдиреНрдпреВрдирддрдо рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдХрдИ рд╢рд╛рдо рдФрд░ рдХреБрдЫ рджрд┐рди рдмрд┐рддрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдЗрд╕ рдХреЛрдб рдХреЛ рдХреНрд░рдо рдореЗрдВ рд░рдЦрд╛ рдФрд░ рдЗрд╕реЗ
GitHub рдкрд░ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХреНрдпрд╛ рдФрд░ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕ рдкрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВред
рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рдореЛрдб рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд░реНрдЪреБрдЕрд▓ "рд╕реЗрдВрд╕рд░" рдФрд░ "рдСрдмреНрдЬрд░реНрд╡рд░" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рд╣реИред

тЦМ рд╕рдВрд╕реНрдерд╛рдУрдВ рдФрд░ рдкрд░рд┐рднрд╛рд╖рд╛рдПрдБ
рдЖрдзрд╛рд░ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ:
- рд╕реЗрдВрд╕рд░ - рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рдВрдХреЗрддрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ;
- рдкреНрд░реЗрдХреНрд╖рдХ - рдПрдХ, рдпрд╛ рдХрдИ рд╕реЗрдВрд╕рд░ рд╕реЗ рдкреВрдЫрддрд╛рдЫ рдХрд░рддрд╛ рд╣реИред рд╕реЗрдВрд╕рд░ рдХреА рд╡рд░реНрддрдорд╛рди рд░реАрдбрд┐рдВрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЗрд╕рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрддрд╛ рд╣реИ;
- рд╕реНрдЯреЗрдЯ рдХреИрд▓рдХреБрд▓реЗрдЯрд░ - рдореИрдЯреНрд░рд┐рдХреНрд╕ рд▓реЙрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред
- рд░рд╛рдЬреНрдп рд▓реЙрдЧ - рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдВрд╕рд░ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрддрдХ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдЬреЛ рдорддрджрд╛рди рдХреЗ рд╕рдордп рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред
рдкреНрд░рддреНрдпреЗрдХ рдЕрдореВрд░реНрдд рдХреЗ рд▓рд┐рдП, рдПрдХ рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рд╕рд╛рде рд╣реА рд╕рд░рд▓ рдФрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд▓рд┐рдП рддрдВрддреНрд░ рднреА рд╣реИред рдЖрдЗрдП рдЙрди рдкрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
рд╕реЗрдВрд╕рд░
рдмреБрдирд┐рдпрд╛рджреА
рдЖрдИрдкреАрдУ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ред IProbe рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрдХреНрд╖рд╛рдПрдВ рдЕрдиреБрд░реЛрдз рдкрд░, рд╕рд┐рд╕реНрдЯрдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдорд╛рди рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рддреА рд╣реИрдВ, рдпрд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореЙрдбреНрдпреВрд▓ / рд╕реЗрд╡рд╛ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИрдВред
public interface IProbe { string Name { get; } Task<ProbeResult> Check(); }
рдЪреЗрдХ рд╡рд┐рдзрд┐ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, IProbe рдЙрджрд╛рд╣рд░рдг рдПрдХ ProbeResult рд╕рдВрд░рдЪрдирд╛ рджреЗрддрд╛ рд╣реИ
public struct ProbeResult { public string ProbeName { get; set; } public DateTime Time { get; set; } public bool Success { get; set; } public string Data { get; set; } public Exception Exception { get; set; } public override string ToString() => $"{Time}: {Success}"; }
рдЬрд╣рд╛рдВ рд╕рдлрд▓рддрд╛ рдХреНрд╖реЗрддреНрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╕реЗрдВрд╕рд░ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдбреЗрдЯрд╛ рдФрд░ рдПрдХреНрд╕реЗрдкреНрд╢рди рдлрд╝реАрд▓реНрдб рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐ рдпрд╣ рдбреАрдмрдЧрд┐рдВрдЧ, рдпрд╛ рд▓реЙрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдкреНрд░реЗрдХреНрд╖рдХ
ISpectator рдХрд╛ рдореВрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ред рдпрд╣ рд╕рд┐рд╕реНрдЯрдо рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддрд╛ рд╣реИ, рдЗрди рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдм рдХрд┐рдП рдЧрдП рд╕рднреА рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд╕рдордп рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП IStateEvaluator рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
public interface ISpectator<TState> where TState : struct, IConvertible { event EventHandler<StateEventArgs<TState>> StateChanged; event EventHandler<HealthCheckEventArgs> HealthChecked; TState State { get; } TimeSpan Uptime { get; } string Name { get; } void AddProbe(IProbe probe); void CheckHealth(); }
рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдВрд╕рд░ рдХреЗ рдЪреБрдирд╛рд╡реЛрдВ рдХреЗ рджреМрд░рд╛рди, рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рд╕реНрдЯреЗрдЯрдЪреЗрдирдб рдЗрд╡реЗрдВрдЯ рдХреЛ рдЙрдард╛рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕ рдИрд╡реЗрдВрдЯ рдХреЗ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк
рд╕реНрдЯреЗрдЯрдИрд╡реЗрдВрдЯ рдПрдЧреНрд╕ рдХрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрддреА рд╣реИред
рд░рд╛рдЬреНрдп рдХреИрд▓рдХреБрд▓реЗрдЯрд░
рдмреЗрд╕
IEvaluator рдЗрдВрдЯрд░рдлрд╝реЗрд╕ред рд╕реЗрдВрд╕рд░ рд╕реНрдерд┐рддрд┐ рд▓реЙрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред
public interface IStateEvaluator<TState> { TState Evaluate( TState currentState, DateTime stateChangedLastTime, IReadOnlyCollection<JournalRecord> journal); }
рд░рд╛рдЬреНрдп рд▓реЙрдЧ
рдЬрд░реНрдирд▓рдХреЙрд░реНрдб рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ред рдЬрд░реНрдирд▓ рдЖрд░рдХреЙрд░реНрдб рдЙрджрд╛рд╣рд░рдг рдЙрди рд╕рднреА рд╕реЗрдВрд╕рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рджреНрд╡рд╛рд░рд╛ рдорддрджрд╛рди рдХреЗ рд╕рдордп рд╢реБрд░реВ рдХрд┐рдП рдЧрдП рдереЗред
public struct JournalRecord { public JournalRecord(DateTime time, IEnumerable<ProbeResult> values) { Time = time; Values = values.ToImmutableList(); } public DateTime Time { get; set; } public IReadOnlyCollection<ProbeResult> Values { get; set; } public override string ToString() => $"{Time}: [{string.Join(",", Values)}]"; }
Works рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдПрдореНрдмреЗрдбреЗрдб рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдВрд╕рд░ рдордирд╛рдпрд╛ рдкреНрд░рдгрд╛рд▓реА / рдореЙрдбреНрдпреВрд▓ / рд╕реЗрд╡рд╛ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдмрд╛рд╣рд░реА рд╕рдХреНрд░рд┐рдп рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛, рдЙрдкрдпреЛрдЧ рдХреА рдЧрдИ рд░реИрдо рдХреА рдорд╛рддреНрд░рд╛, рдХреИрд╢ рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЖрджрд┐ рдХреЛ рдареАрдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдВрд╕рд░ рдХреЛ рдПрдХ рдпрд╛ рдХрдИ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХреЛрдВ рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдПрдХ рдпрд╛ рдХрдИ рд╕реЗрдВрд╕рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдХреЛ ISpectator рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рд░рд╛рдЬреНрдп рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╛ рд╕реЗрдВрд╕рд░ рдХрд╛ рдЪреБрдирд╛рд╡ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЕрдЧрд▓реА рдЬрд╛рдВрдЪ рдХреЗ рджреМрд░рд╛рди, рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдЕрдкрдиреЗ рд╕рднреА "рд╕реЗрдВрд╕рд░" рдХреЛ рдкреЛрд▓ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд░рд╛рдЬреНрдп рд▓реЙрдЧ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рдгреА рдмрдирд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдмрджрд▓ рдЧрдИ рд╣реИ, рддреЛ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдШрдЯрдирд╛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЗрд╡реЗрдВрдЯ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕реА рд╕рдордп, рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ "рдХрдВрдкреНрдпреВрдЯрд░" рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдФрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рдореЛрдб
рджреЛ рдореБрдЦреНрдп рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬрд┐рд╕рдореЗрдВ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ "рд╕реЗрдВрд╕рд░" рдХрд╛ рд╕рд░реНрд╡реЗрдХреНрд╖рдг рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред
рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдореЛрдб
рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рдмрд╛рдж рд╕реЗрдВрд╕рд░ рдХрд╛ рдПрдХ рд╕рд░реНрд╡реЗрдХреНрд╖рдг рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдХреЗ рд▓рд┐рдП рд╕рд┐рд╕реНрдЯрдо рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╕реЗ рдПрдХ рдХреА рдкреНрд░рддреНрдпрдХреНрд╖ рдЕрдкреАрд▓ рдХреЗ рдХрд╛рд░рдг рд╣реЛрддрд╛ рд╣реИред
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдФрд░ рд╕реЗрдВрд╕рд░ рдПрдХ рд╣реА рдзрд╛рдЧреЗ рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЧрд▓рдд рдирд┐рд░реНрдзрд╛рд░рдг рд╕рд┐рд╕реНрдЯрдо рдХреЗ рднреАрддрд░ рдПрдХ рдСрдкрд░реЗрд╢рди рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдХрд╛ рдореВрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ -
SpectatorBase ред
рдХреЛрдб рджреЗрдЦреЗрдВ public class SpectatorBase<TState> : ISpectator<TState> where TState : struct, IConvertible { private TState _state; private readonly IList<IProbe> _probes; private readonly IStateEvaluator<TState> _stateEvaluator; private readonly List<JournalRecord> _journal; private readonly ReaderWriterLockSlim _journalLock; private readonly ReaderWriterLockSlim _stateLock; private readonly Stopwatch _stopwatch; public event EventHandler<StateEventArgs<TState>> StateChanged; public event EventHandler<HealthCheckEventArgs> HealthChecked; public virtual TState State { get { _stateLock.EnterReadLock(); try { return _state; } finally { _stateLock.ExitReadLock(); } } } public TimeSpan Uptime => _stopwatch.Elapsed; public string Name { get; set; } public IReadOnlyCollection<JournalRecord> Journal { get { _journalLock.EnterReadLock(); try { return _journal; } finally { _journalLock.ExitReadLock(); } } } public DateTime StateChangedDate { get; private set; } public TimeSpan RetentionPeriod { get; private set; } public SpectatorBase(IStateEvaluator<TState> stateEvaluator, TimeSpan retentionPeriod, TState initialState) { RetentionPeriod = retentionPeriod; _state = initialState; StateChangedDate = DateTime.UtcNow; _stateEvaluator = stateEvaluator; _stopwatch = Stopwatch.StartNew(); _probes = new List<IProbe>(); _journal = new List<JournalRecord>(); _journalLock = new ReaderWriterLockSlim(); _stateLock = new ReaderWriterLockSlim(); } public void AddProbe(IProbe probe) => _probes.Add(probe); protected virtual void ChangeState(TState state, IEnumerable<string> failedProbes) { _stateLock.EnterWriteLock(); try { _state = state; } finally { _stateLock.ExitWriteLock(); } StateChangedDate = DateTime.UtcNow; StateChanged?.Invoke(this, new StateEventArgs<TState>(state, StateChangedDate, failedProbes)); } public virtual void CheckHealth() { var results = new Stack<ProbeResult>(); var tasks = _probes .Select(async o => { results.Push(await o.Check().ConfigureAwait(false)); }) .ToArray(); Task.WaitAll(tasks); var now = DateTime.UtcNow; _journalLock.EnterWriteLock(); try {
рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдореЛрдб
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕реЗрдВрд╕рд░ рдХреА рдкреВрдЫрддрд╛рдЫ рд╕рд┐рд╕реНрдЯрдо рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рд╕реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рд╣реЛрддреА рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдХрд╛ рдореВрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИ -
рдСрдЯреЛрдореЗрдЯреЗрдбрд╕реНрдкреЗрдХреНрдЯрд░ ред
рдХреЛрдб рджреЗрдЦреЗрдВ public class AutomatedSpectator<TState> : SpectatorBase<TState>, IAutomatedSpectator<TState> where TState : struct, IConvertible { public TimeSpan CheckHealthPeriod { get; } private readonly System.Timers.Timer _timer; public AutomatedSpectator( TimeSpan checkHealthPeriod, TimeSpan retentionPeriod, IStateEvaluator<TState> stateEvaluator, TState initialState) : base(stateEvaluator, retentionPeriod, initialState) { CheckHealthPeriod = checkHealthPeriod; _timer = new System.Timers.Timer(CheckHealthPeriod.TotalMilliseconds); _timer.Elapsed += (sender, args) => CheckHealth(); _timer.AutoReset = true; } public void Start() => _timer.Start(); }
тЦМ рдирд┐рд╖реНрдХрд░реНрд╖
X.Spectator рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдореБрдЭреЗ рдХрдИ рд╕реЗрд╡рд╛рдУрдВ рдХреА рд╕реНрдерд┐рд░рддрд╛ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдЕрддреНрдпрдзрд┐рдХ рднрд░реА рд╣реБрдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдорджрдж рдорд┐рд▓реАред рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдврд╛рдВрдЪрд╛ рдЦреБрдж рдХреЛ рд╕рд╛рдмрд┐рдд рдХрд░ рджрд┐рдпрд╛ рд╣реИ рдЬрдм рдорд╛рдЗрдХреНрд░реЛрд╕рд┐рд╕реНрдЯрд╡рд░реНрдХ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдирд┐рд░реНрдорд┐рдд рд╡рд┐рддрд░рд┐рдд рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕рдмрд╕реЗ рдЗрд╖реНрдЯрддрдо рдПрдХреАрдХрд░рдг рд╡рд┐рдХрд▓реНрдк рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рд╡реНрдпреБрддреНрдХреНрд░рдо рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреН, рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдЬрдм рдПрдХ рдЖрдИрдУрд╕реА рдХрдВрдЯреЗрдирд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реЗрдВрд╕рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХреЛрдВ рдХреЛ рд╕рд┐рдВрдЧрд▓рдЯрди рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛ рдПрдХ рдПрдХрд▓ рдЙрджрд╛рд╣рд░рдг рдореЙрдбреНрдпреВрд▓ рдФрд░ рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╡рд░реНрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкрд╣реБрдБрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
Information рд▓рд┐рдВрдХ рдФрд░ рдЙрдкрдпреЛрдЧреА рдЬрд╛рдирдХрд╛рд░реА
тЖТ
рдкрд░рд┐рдпреЛрдЬрдирд╛ рднрдВрдбрд╛рд░тЖТ
рдЙрджрд╛рд╣рд░рдгтЖТ
рдиреБрдЧреЗрдЯ рдкреИрдХреЗрдЬ