Bearsampp 2026.7.11
Loading...
Searching...
No Matches
ServiceHelper Class Reference

Static Public Member Functions

static getAllServiceNames ()
static getBinFromServiceName ($serviceName, $bearsamppBins)
static getServiceDisplayName ($bin, $service)
static getServicePort ($serviceName, $bearsamppBins)
static getSyntaxCheckCmd ($serviceName, $bearsamppBins=null)
static hasSyntaxCheck ($serviceName)
static processServices ($bearsamppBins, callable $callback)
static restartService ($service)
static startAllServicesParallel ($serviceInfos, ?callable $progressCallback=null, $startupTimeout=30)
static startService ($bin, $syntaxCheckCmd=null, $showErrors=true)
static stopAllServicesParallel ($bearsamppBins, ?callable $progressCallback=null, $shutdownTimeout=15)
static stopService ($service)

Static Private Member Functions

static allServicesRunning ($serviceInfos)
static allServicesStopped ($services)
static forceKillService ($serviceName)
static initializeMappings ($bearsamppBins)
static shutdownServicesParallel ($services, ?callable $progressCallback=null, $shutdownTimeout=15)
static shutdownServicesSequential ($services, ?callable $progressCallback=null)
static startServicesParallel ($serviceInfos, ?callable $progressCallback=null, $startupTimeout=30)
static startServicesSequential ($serviceInfos, ?callable $progressCallback=null)

Static Private Attributes

static $serviceMap = null
static $syntaxCheckMap = null

Detailed Description

Class ServiceHelper

Utility class for service management operations. Provides centralized methods for service lookup, syntax check commands, and common service operations to eliminate code duplication.

Definition at line 17 of file class.servicehelper.php.

Member Function Documentation

◆ allServicesRunning()

allServicesRunning ( $serviceInfos)
staticprivate

Check if all services are running

Parameters
array$serviceInfosArray of service information
Returns
bool True if all services are running

Definition at line 579 of file class.servicehelper.php.

580 {
581 foreach ($serviceInfos as $serviceName => $serviceInfo) {
582 $service = $serviceInfo['service'];
583 if (!$service->isRunning()) {
584 return false;
585 }
586 }
587 return true;
588 }

Referenced by startServicesParallel(), and startServicesSequential().

Here is the caller graph for this function:

◆ allServicesStopped()

allServicesStopped ( $services)
staticprivate

Check if all services are stopped

Parameters
array$servicesArray of services
Returns
bool True if all services are stopped

Definition at line 397 of file class.servicehelper.php.

398 {
399 foreach ($services as $serviceName => $service) {
400 if (!$service->isStopped()) {
401 return false;
402 }
403 }
404 return true;
405 }

Referenced by shutdownServicesParallel(), and shutdownServicesSequential().

Here is the caller graph for this function:

◆ forceKillService()

forceKillService ( $serviceName)
staticprivate

Force kill a service by process name

Parameters
string$serviceNameThe service name
Returns
bool True if force kill was executed

Definition at line 369 of file class.servicehelper.php.

370 {
371 $processMap = [
372 BinApache::SERVICE_NAME => 'httpd.exe',
373 BinMysql::SERVICE_NAME => 'mysqld.exe',
374 BinMariadb::SERVICE_NAME => 'mysqld.exe',
375 BinMailpit::SERVICE_NAME => 'mailpit.exe',
376 BinMemcached::SERVICE_NAME => 'memcached.exe',
377 BinPostgresql::SERVICE_NAME => 'postgres.exe',
378 BinXlight::SERVICE_NAME => 'xlightftpd.exe',
379 'nodejs' => 'node.exe', // NodeJS - not a Windows service but needs to be killed on exit
380 ];
381
382 if (isset($processMap[$serviceName])) {
383 Log::trace('Killing process: ' . $processMap[$serviceName]);
384 Win32Ps::killBins([$processMap[$serviceName]]);
385 return true;
386 }
387
388 return false;
389 }
const SERVICE_NAME
static trace($data, $file=null)
static killBins($refreshProcs=false)

References Win32Ps\killBins(), BinApache\SERVICE_NAME, BinMailpit\SERVICE_NAME, BinMariadb\SERVICE_NAME, BinMemcached\SERVICE_NAME, BinMysql\SERVICE_NAME, BinPostgresql\SERVICE_NAME, BinXlight\SERVICE_NAME, and Log\trace().

Referenced by shutdownServicesParallel(), and shutdownServicesSequential().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getAllServiceNames()

◆ getBinFromServiceName()

getBinFromServiceName ( $serviceName,
$bearsamppBins )
static

Get binary instance from service name

Parameters
string$serviceNameThe service name
object$bearsamppBinsThe bins object
Returns
object|null The binary instance or null if not found

Definition at line 67 of file class.servicehelper.php.

68 {
70 return isset(self::$serviceMap[$serviceName]) ? self::$serviceMap[$serviceName] : null;
71 }
global $bearsamppBins
static initializeMappings($bearsamppBins)

References $bearsamppBins, and initializeMappings().

Referenced by getServicePort(), processServices(), and ActionRestartAllServices\processWindow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getServiceDisplayName()

getServiceDisplayName ( $bin,
$service )
static

Get service display name (Name + Version + Service Name)

Parameters
object$binThe binary instance
object$serviceThe service instance
Returns
string The formatted service name

Definition at line 95 of file class.servicehelper.php.

96 {
97 return $bin->getName() . ' ' . $bin->getVersion() . ' (' . $service->getName() . ')';
98 }

Referenced by ActionRestartAllServices\processWindow(), and ActionStartAllServices\processWindow().

Here is the caller graph for this function:

◆ getServicePort()

getServicePort ( $serviceName,
$bearsamppBins )
static

Get port for a service

Parameters
string$serviceNameThe service name
object$bearsamppBinsThe bins object
Returns
int The port number or 0 if not applicable

Definition at line 200 of file class.servicehelper.php.

201 {
202 $bin = self::getBinFromServiceName($serviceName, $bearsamppBins);
203 if ($bin === null) {
204 return 0;
205 }
206
207 // Different services have different methods to get port
208 if (method_exists($bin, 'getPort')) {
209 return $bin->getPort();
210 } elseif (method_exists($bin, 'getSmtpPort')) {
211 return $bin->getSmtpPort();
212 }
213
214 return 0;
215 }
static getBinFromServiceName($serviceName, $bearsamppBins)

References $bearsamppBins, and getBinFromServiceName().

Here is the call graph for this function:

◆ getSyntaxCheckCmd()

getSyntaxCheckCmd ( $serviceName,
$bearsamppBins = null )
static

Get syntax check command for a service

Parameters
string$serviceNameThe service name
object$bearsamppBinsThe bins object (for initialization)
Returns
string|null The syntax check command or null if not applicable

Definition at line 80 of file class.servicehelper.php.

81 {
82 if ($bearsamppBins !== null) {
84 }
85 return isset(self::$syntaxCheckMap[$serviceName]) ? self::$syntaxCheckMap[$serviceName] : null;
86 }

References $bearsamppBins, and initializeMappings().

Referenced by processServices(), and ActionRestartAllServices\processWindow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hasSyntaxCheck()

hasSyntaxCheck ( $serviceName)
static

Check if a service has syntax check capability

Parameters
string$serviceNameThe service name
Returns
bool True if service supports syntax check

Definition at line 180 of file class.servicehelper.php.

181 {
182 if (self::$syntaxCheckMap === null) {
183 // Initialize with dummy bins object if needed
184 self::$syntaxCheckMap = [
188 ];
189 }
190 return isset(self::$syntaxCheckMap[$serviceName]);
191 }
const CMD_SYNTAX_CHECK
const CMD_SYNTAX_CHECK

References BinApache\CMD_SYNTAX_CHECK, BinMariadb\CMD_SYNTAX_CHECK, BinMysql\CMD_SYNTAX_CHECK, BinApache\SERVICE_NAME, BinMariadb\SERVICE_NAME, and BinMysql\SERVICE_NAME.

◆ initializeMappings()

initializeMappings ( $bearsamppBins)
staticprivate

Initialize service mappings

Parameters
object$bearsamppBinsThe bins object
Returns
void

Definition at line 37 of file class.servicehelper.php.

38 {
39 if (self::$serviceMap === null) {
40 self::$serviceMap = [
48 ];
49 }
50
51 if (self::$syntaxCheckMap === null) {
52 self::$syntaxCheckMap = [
56 ];
57 }
58 }

References $bearsamppBins, BinApache\CMD_SYNTAX_CHECK, BinMariadb\CMD_SYNTAX_CHECK, BinMysql\CMD_SYNTAX_CHECK, BinApache\SERVICE_NAME, BinMailpit\SERVICE_NAME, BinMariadb\SERVICE_NAME, BinMemcached\SERVICE_NAME, BinMysql\SERVICE_NAME, BinPostgresql\SERVICE_NAME, and BinXlight\SERVICE_NAME.

Referenced by getBinFromServiceName(), getSyntaxCheckCmd(), and processServices().

Here is the caller graph for this function:

◆ processServices()

processServices ( $bearsamppBins,
callable $callback )
static

Process all services with a callback function

Parameters
object$bearsamppBinsThe bins object
callable$callbackFunction to call for each service: function($serviceName, $service, $bin, $syntaxCheckCmd)
Returns
void

Definition at line 107 of file class.servicehelper.php.

108 {
110
111 foreach ($bearsamppBins->getServices() as $serviceName => $service) {
112 $bin = self::getBinFromServiceName($serviceName, $bearsamppBins);
113 $syntaxCheckCmd = self::getSyntaxCheckCmd($serviceName);
114
115 if ($bin !== null) {
116 $callback($serviceName, $service, $bin, $syntaxCheckCmd);
117 }
118 }
119 }
static getSyntaxCheckCmd($serviceName, $bearsamppBins=null)

References $bearsamppBins, getBinFromServiceName(), getSyntaxCheckCmd(), and initializeMappings().

Referenced by ActionStartAllServices\processWindow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restartService()

restartService ( $service)
static

Restart a service

Parameters
object$serviceThe service instance
Returns
bool True if service restarted successfully, false otherwise

Definition at line 151 of file class.servicehelper.php.

152 {
153 return $service->restart();
154 }

◆ shutdownServicesParallel()

shutdownServicesParallel ( $services,
?callable $progressCallback = null,
$shutdownTimeout = 15 )
staticprivate

Shutdown services in parallel (non-blocking)

Phase 1: Send stop commands to all services (non-blocking) Phase 2: Monitor their status until all stopped or timeout Phase 3: Force kill any services still running

Parameters
array$servicesArray of services
callable | null$progressCallbackOptional progress callback
int$shutdownTimeoutTimeout in seconds
Returns
bool True if all services stopped

Definition at line 274 of file class.servicehelper.php.

275 {
276 Log::trace('Phase 1: Sending stop commands to all services');
277 $totalServices = count($services);
278 $currentIndex = 0;
279
280 // Phase 1: Send stop commands (non-blocking)
281 foreach ($services as $serviceName => $service) {
282 $currentIndex++;
283 if ($progressCallback) {
284 $progressCallback($currentIndex, $totalServices, $serviceName);
285 }
286
287 Log::trace('Sending stop to: ' . $serviceName);
288 $service->stop();
289 }
290
291 // Phase 2: Monitor status
292 Log::trace('Phase 2: Monitoring service status');
293 $monitorStartTime = microtime(true);
294 $monitorTimeout = $shutdownTimeout;
295 $checkInterval = 0.5;
296 $allStopped = false;
297
298 while ((microtime(true) - $monitorStartTime) < $monitorTimeout) {
299 $allStopped = true;
300
301 foreach ($services as $serviceName => $service) {
302 if (!$service->isStopped()) {
303 $allStopped = false;
304 break;
305 }
306 }
307
308 if ($allStopped) {
309 Log::trace('All services stopped in parallel phase');
310 return true;
311 }
312
313 usleep($checkInterval * 1000000);
314 }
315
316 // Phase 3: Force kill remaining services
317 Log::trace('Phase 3: Force killing remaining services');
318 foreach ($services as $serviceName => $service) {
319 if (!$service->isStopped()) {
320 Log::trace('Force killing: ' . $serviceName);
321 self::forceKillService($serviceName);
322 }
323 }
324
325 // Final check
326 return self::allServicesStopped($services);
327 }
static forceKillService($serviceName)
static allServicesStopped($services)

References allServicesStopped(), forceKillService(), and Log\trace().

Referenced by stopAllServicesParallel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdownServicesSequential()

shutdownServicesSequential ( $services,
?callable $progressCallback = null )
staticprivate

Shutdown services sequentially (fallback method)

Stops services one by one, waiting for each to complete. Used as fallback when parallel shutdown fails.

Parameters
array$servicesArray of services
callable | null$progressCallbackOptional progress callback
Returns
bool True if all services stopped

Definition at line 339 of file class.servicehelper.php.

340 {
341 Log::trace('Starting sequential shutdown phase');
342 $totalServices = count($services);
343 $currentIndex = 0;
344
345 foreach ($services as $serviceName => $service) {
346 $currentIndex++;
347 if ($progressCallback) {
348 $progressCallback($currentIndex, $totalServices, $serviceName);
349 }
350
351 Log::trace('Sequential stop: ' . $serviceName);
352 $service->stop();
353
354 if (!$service->isStopped()) {
355 Log::trace('Force killing: ' . $serviceName);
356 self::forceKillService($serviceName);
357 }
358 }
359
360 return self::allServicesStopped($services);
361 }

References allServicesStopped(), forceKillService(), and Log\trace().

Referenced by stopAllServicesParallel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ startAllServicesParallel()

startAllServicesParallel ( $serviceInfos,
?callable $progressCallback = null,
$startupTimeout = 30 )
static

Start all services in parallel for optimized startup

Sends start commands to all services simultaneously, then monitors their status. Falls back to sequential startup if parallel fails. Significantly reduces startup time.

Performance: 40-60% faster startup (parallel vs sequential)

Parameters
array$serviceInfosArray of service information arrays with 'service', 'bin', 'name' keys
callable | null$progressCallbackOptional callback: function($current, $total, $serviceName)
int$startupTimeoutTimeout in seconds (default: 30)
Returns
bool True if all services started successfully

Definition at line 420 of file class.servicehelper.php.

421 {
422 Log::trace('ServiceHelper::startAllServicesParallel() starting with ' . count($serviceInfos) . ' services');
423 $startTime = microtime(true);
424
425 if (empty($serviceInfos)) {
426 Log::trace('No services to start');
427 return true;
428 }
429
430 Log::trace('Starting parallel startup of ' . count($serviceInfos) . ' services');
431
432 // Try parallel startup
433 $parallelSuccess = self::startServicesParallel($serviceInfos, $progressCallback, $startupTimeout);
434
435 if ($parallelSuccess) {
436 $duration = round(microtime(true) - $startTime, 3);
437 Log::info('Parallel startup completed successfully in ' . $duration . 's');
438 return true;
439 }
440
441 // Fallback to sequential
442 Log::info('Parallel startup timed out, falling back to sequential startup');
443 $sequentialSuccess = self::startServicesSequential($serviceInfos, $progressCallback);
444
445 $totalDuration = round(microtime(true) - $startTime, 3);
446 Log::info('Sequential startup completed in ' . $totalDuration . 's');
447
448 return $sequentialSuccess;
449 }
static info($data, $file=null)
static startServicesParallel($serviceInfos, ?callable $progressCallback=null, $startupTimeout=30)
static startServicesSequential($serviceInfos, ?callable $progressCallback=null)

References Log\info(), startServicesParallel(), startServicesSequential(), and Log\trace().

Referenced by ActionStartup\installServicesSequential().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ startService()

startService ( $bin,
$syntaxCheckCmd = null,
$showErrors = true )
static

Start a service with optional syntax check

Parameters
object$binThe binary instance
string | null$syntaxCheckCmdThe syntax check command (optional)
bool$showErrorsWhether to show error messages (default: true)
Returns
bool True if service started successfully, false otherwise

Definition at line 129 of file class.servicehelper.php.

130 {
131 return Util::startService($bin, $syntaxCheckCmd, $showErrors);
132 }
static startService($bin, $syntaxCheckCmd, $showWindow=false)

References Util\startService().

Referenced by ActionRestartAllServices\processWindow(), and ActionStartAllServices\processWindow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ startServicesParallel()

startServicesParallel ( $serviceInfos,
?callable $progressCallback = null,
$startupTimeout = 30 )
staticprivate

Start services in parallel (non-blocking)

Phase 1: Send start commands to all services (non-blocking) Phase 2: Monitor their status until all running or timeout Phase 3: Retry any services that failed to start

Parameters
array$serviceInfosArray of service information
callable | null$progressCallbackOptional progress callback
int$startupTimeoutTimeout in seconds
Returns
bool True if all services started

Definition at line 463 of file class.servicehelper.php.

464 {
465 Log::trace('Phase 1: Sending start commands to all services');
466 $totalServices = count($serviceInfos);
467 $currentIndex = 0;
468
469 // Phase 1: Send start commands (non-blocking)
470 foreach ($serviceInfos as $serviceName => $serviceInfo) {
471 $currentIndex++;
472 if ($progressCallback) {
473 $progressCallback($currentIndex, $totalServices, $serviceInfo['name']);
474 }
475
476 Log::trace('Sending start to: ' . $serviceName);
477 $service = $serviceInfo['service'];
478
479 // Start the service
480 $service->start();
481 }
482
483 // Phase 2: Monitor status
484 Log::trace('Phase 2: Monitoring service status');
485 $monitorStartTime = microtime(true);
486 $monitorTimeout = $startupTimeout;
487 $checkInterval = 0.5;
488 $allRunning = false;
489 $failedServices = [];
490
491 while ((microtime(true) - $monitorStartTime) < $monitorTimeout) {
492 $allRunning = true;
493
494 foreach ($serviceInfos as $serviceName => $serviceInfo) {
495 $service = $serviceInfo['service'];
496
497 if (!$service->isRunning()) {
498 $allRunning = false;
499 $failedServices[$serviceName] = $serviceInfo;
500 }
501 }
502
503 if ($allRunning) {
504 Log::trace('All services running in parallel phase');
505 return true;
506 }
507
508 usleep($checkInterval * 1000000);
509 }
510
511 // Phase 3: Retry failed services
512 if (!empty($failedServices)) {
513 Log::trace('Phase 3: Retrying ' . count($failedServices) . ' failed services');
514
515 foreach ($failedServices as $serviceName => $serviceInfo) {
516 $service = $serviceInfo['service'];
517
518 if (!$service->isRunning()) {
519 Log::trace('Retrying start for: ' . $serviceName);
520 $service->start();
521 usleep(500000); // 500ms delay between retries
522 }
523 }
524
525 // Final check
526 return self::allServicesRunning($serviceInfos);
527 }
528
529 return true;
530 }
static allServicesRunning($serviceInfos)

References allServicesRunning(), and Log\trace().

Referenced by startAllServicesParallel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ startServicesSequential()

startServicesSequential ( $serviceInfos,
?callable $progressCallback = null )
staticprivate

Start services sequentially (fallback method)

Starts services one by one, waiting for each to complete. Used as fallback when parallel startup fails.

Parameters
array$serviceInfosArray of service information
callable | null$progressCallbackOptional progress callback
Returns
bool True if all services started

Definition at line 542 of file class.servicehelper.php.

543 {
544 Log::trace('Starting sequential startup phase');
545 $totalServices = count($serviceInfos);
546 $currentIndex = 0;
547
548 foreach ($serviceInfos as $serviceName => $serviceInfo) {
549 $currentIndex++;
550 if ($progressCallback) {
551 $progressCallback($currentIndex, $totalServices, $serviceInfo['name']);
552 }
553
554 Log::trace('Sequential start: ' . $serviceName);
555 $service = $serviceInfo['service'];
556
557 $service->start();
558
559 // Small delay between service starts
560 usleep(200000);
561
562 if (!$service->isRunning()) {
563 Log::trace('Service failed to start: ' . $serviceName);
564 // Retry once
565 $service->start();
566 usleep(500000);
567 }
568 }
569
570 return self::allServicesRunning($serviceInfos);
571 }

References allServicesRunning(), and Log\trace().

Referenced by startAllServicesParallel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stopAllServicesParallel()

stopAllServicesParallel ( $bearsamppBins,
?callable $progressCallback = null,
$shutdownTimeout = 15 )
static

Stop all services in parallel for optimized shutdown

Sends stop commands to all services simultaneously, then monitors their status. Falls back to sequential shutdown if parallel fails. Significantly reduces shutdown time.

Performance: 40-60% faster shutdown (parallel vs sequential)

Parameters
object$bearsamppBinsThe bins object
callable | null$progressCallbackOptional callback: function($current, $total, $serviceName)
int$shutdownTimeoutTimeout in seconds (default: 15)
Returns
bool True if all services stopped successfully

Definition at line 230 of file class.servicehelper.php.

231 {
232 Log::trace('ServiceHelper::stopAllServicesParallel() starting');
233 $startTime = microtime(true);
234
235 $services = $bearsamppBins->getServices();
236 if (empty($services)) {
237 Log::trace('No services to shut down');
238 return true;
239 }
240
241 Log::trace('Starting parallel shutdown of ' . count($services) . ' services');
242
243 // Try parallel shutdown
244 $parallelSuccess = self::shutdownServicesParallel($services, $progressCallback, $shutdownTimeout);
245
246 if ($parallelSuccess) {
247 $duration = round(microtime(true) - $startTime, 3);
248 Log::info('Parallel shutdown completed successfully in ' . $duration . 's');
249 return true;
250 }
251
252 // Fallback to sequential
253 Log::info('Parallel shutdown timed out, falling back to sequential shutdown');
254 $sequentialSuccess = self::shutdownServicesSequential($services, $progressCallback);
255
256 $totalDuration = round(microtime(true) - $startTime, 3);
257 Log::info('Sequential shutdown completed in ' . $totalDuration . 's');
258
259 return $sequentialSuccess;
260 }
static shutdownServicesSequential($services, ?callable $progressCallback=null)
static shutdownServicesParallel($services, ?callable $progressCallback=null, $shutdownTimeout=15)

References $bearsamppBins, Log\info(), shutdownServicesParallel(), shutdownServicesSequential(), and Log\trace().

Referenced by ActionStopAllServices\processWindow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stopService()

stopService ( $service)
static

Stop a service

Parameters
object$serviceThe service instance
Returns
bool True if service stopped successfully, false otherwise

Definition at line 140 of file class.servicehelper.php.

141 {
142 return $service->stop();
143 }

Referenced by ActionRestartAllServices\processWindow().

Here is the caller graph for this function:

Field Documentation

◆ $serviceMap

$serviceMap = null
staticprivate

Definition at line 23 of file class.servicehelper.php.

◆ $syntaxCheckMap

$syntaxCheckMap = null
staticprivate

Definition at line 29 of file class.servicehelper.php.


The documentation for this class was generated from the following file: