Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34621418
PhabricatorDatabaseHealthRecord.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
4 KB
Subscribers
None
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
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Tue, Jan 20, 1:19 AM (1 h, 7 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
48/51/3fee5163f8b7587ac4e8c9b64a74
Attached To
rPHAB Phabricator
Event Timeline
Log In to Comment