Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F93659110
PhabricatorDatabaseHealthRecord.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Nov 30, 12:40
Size
4 KB
Mime Type
text/x-php
Expires
Mon, Dec 2, 12:40 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
22683212
Attached To
rPH Phabricator
PhabricatorDatabaseHealthRecord.php
View Options
<?php
final
class
PhabricatorDatabaseHealthRecord
extends
Phobject
{
private
$ref
;
private
$shouldCheck
;
private
$isHealthy
;
private
$upEventCount
;
private
$downEventCount
;
public
function
__construct
(
PhabricatorDatabaseRef
$ref
)
{
$this
->
ref
=
$ref
;
$this
->
readState
();
}
/**
* Is the database currently healthy?
*/
public
function
getIsHealthy
()
{
return
$this
->
isHealthy
;
}
/**
* Should this request check database health?
*/
public
function
getShouldCheck
()
{
return
$this
->
shouldCheck
;
}
/**
* How many recent health checks were successful?
*/
public
function
getUpEventCount
()
{
return
$this
->
upEventCount
;
}
/**
* How many recent health checks failed?
*/
public
function
getDownEventCount
()
{
return
$this
->
downEventCount
;
}
/**
* Number of failures or successes we need to see in a row before we change
* the state.
*/
public
function
getRequiredEventCount
()
{
// NOTE: If you change this value, update the "Cluster: Databases" docs.
return
5
;
}
/**
* Seconds to wait between health checks.
*/
public
function
getHealthCheckFrequency
()
{
// NOTE: If you change this value, update the "Cluster: Databases" docs.
return
3
;
}
public
function
didHealthCheck
(
$result
)
{
$now
=
microtime
(
true
);
$check_frequency
=
$this
->
getHealthCheckFrequency
();
$event_count
=
$this
->
getRequiredEventCount
();
$record
=
$this
->
readHealthRecord
();
$log
=
$record
[
'log'
];
foreach
(
$log
as
$key
=>
$event
)
{
$when
=
idx
(
$event
,
'timestamp'
);
// If the log already has another nearby event, just ignore this one.
// We raced with another process and our result can just be thrown away.
if
((
$now
-
$when
)
<=
$check_frequency
)
{
return
$this
;
}
}
$log
[]
=
array
(
'timestamp'
=>
$now
,
'up'
=>
$result
,
);
// Throw away older events which are now obsolete.
$log
=
array_slice
(
$log
,
-
$event_count
);
$count_up
=
0
;
$count_down
=
0
;
foreach
(
$log
as
$event
)
{
if
(
$event
[
'up'
])
{
$count_up
++;
}
else
{
$count_down
++;
}
}
// If all of the events are the same, change the state.
if
(
$count_up
==
$event_count
)
{
$record
[
'up'
]
=
true
;
}
else
if
(
$count_down
==
$event_count
)
{
$record
[
'up'
]
=
false
;
}
$record
[
'log'
]
=
$log
;
$this
->
writeHealthRecord
(
$record
);
$this
->
isHealthy
=
$record
[
'up'
];
$this
->
shouldCheck
=
false
;
$this
->
updateStatistics
(
$record
);
return
$this
;
}
private
function
readState
()
{
$now
=
microtime
(
true
);
$check_frequency
=
$this
->
getHealthCheckFrequency
();
$record
=
$this
->
readHealthRecord
();
$last_check
=
$record
[
'lastCheck'
];
if
((
$now
-
$last_check
)
>=
$check_frequency
)
{
$record
[
'lastCheck'
]
=
$now
;
$this
->
writeHealthRecord
(
$record
);
$this
->
shouldCheck
=
true
;
}
else
{
$this
->
shouldCheck
=
false
;
}
$this
->
isHealthy
=
$record
[
'up'
];
$this
->
updateStatistics
(
$record
);
}
private
function
updateStatistics
(
array
$record
)
{
$this
->
upEventCount
=
0
;
$this
->
downEventCount
=
0
;
foreach
(
$record
[
'log'
]
as
$event
)
{
if
(
$event
[
'up'
])
{
$this
->
upEventCount
++;
}
else
{
$this
->
downEventCount
++;
}
}
}
private
function
getHealthRecordCacheKey
()
{
$ref
=
$this
->
ref
;
$host
=
$ref
->
getHost
();
$port
=
$ref
->
getPort
();
return
"cluster.db.health({$host}, {$port})"
;
}
private
function
readHealthRecord
()
{
$cache
=
PhabricatorCaches
::
getSetupCache
();
$cache_key
=
$this
->
getHealthRecordCacheKey
();
$health_record
=
$cache
->
getKey
(
$cache_key
);
if
(!
is_array
(
$health_record
))
{
$health_record
=
array
(
'up'
=>
true
,
'lastCheck'
=>
0
,
'log'
=>
array
(),
);
}
return
$health_record
;
}
private
function
writeHealthRecord
(
array
$record
)
{
$cache
=
PhabricatorCaches
::
getSetupCache
();
$cache_key
=
$this
->
getHealthRecordCacheKey
();
$cache
->
setKey
(
$cache_key
,
$record
);
}
}
Event Timeline
Log In to Comment