telegram
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Deploy Telegram Bot / Deploy Telegram Bot (push) Waiting to run
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Deploy Telegram Bot / Deploy Telegram Bot (push) Waiting to run
This commit is contained in:
parent
b058dfaaec
commit
7439c6aaa9
2 changed files with 84 additions and 4 deletions
|
|
@ -56,6 +56,9 @@ ENV BACKEND_URL=https://api.mnemo-cards.online \
|
|||
|
||||
# No EXPOSE needed - bot uses outbound connections only (polling)
|
||||
|
||||
# Signal for graceful shutdown
|
||||
STOPSIGNAL SIGTERM
|
||||
|
||||
# Healthcheck - check if process is running
|
||||
HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start-period=10s \
|
||||
CMD pgrep -f "/app/bot" > /dev/null || exit 1
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:mnemo_cards_telegram_bot/bot_config.dart';
|
||||
|
|
@ -10,10 +11,65 @@ import 'package:mnemo_cards_telegram_bot/backend_client.dart';
|
|||
|
||||
const String version = '0.0.1';
|
||||
|
||||
// Global variables for graceful shutdown
|
||||
BackendClient? _globalBackendClient;
|
||||
TeleDart? _globalTeledart;
|
||||
bool _isShuttingDown = false;
|
||||
final Completer<void> _shutdownCompleter = Completer<void>();
|
||||
|
||||
void main() async {
|
||||
// Setup signal handlers for graceful shutdown
|
||||
ProcessSignal.sigterm.watch().listen((signal) {
|
||||
print('[BOT] Received SIGTERM, shutting down gracefully...');
|
||||
_shutdown();
|
||||
});
|
||||
|
||||
ProcessSignal.sigint.watch().listen((signal) {
|
||||
print('[BOT] Received SIGINT, shutting down gracefully...');
|
||||
_shutdown();
|
||||
});
|
||||
|
||||
return _run();
|
||||
}
|
||||
|
||||
Future<void> _shutdown() async {
|
||||
if (_isShuttingDown) {
|
||||
print('[BOT] Shutdown already in progress');
|
||||
return;
|
||||
}
|
||||
_isShuttingDown = true;
|
||||
|
||||
print('[BOT] Starting graceful shutdown...');
|
||||
|
||||
try {
|
||||
if (_globalTeledart != null) {
|
||||
print('[BOT] Stopping TeleDart...');
|
||||
// TeleDart doesn't have explicit stop method, but we can dispose resources
|
||||
// The process will exit naturally when main completes
|
||||
}
|
||||
} catch (e) {
|
||||
print('[BOT] Error stopping TeleDart: $e');
|
||||
}
|
||||
|
||||
try {
|
||||
if (_globalBackendClient != null) {
|
||||
print('[BOT] Disposing BackendClient...');
|
||||
_globalBackendClient!.dispose();
|
||||
}
|
||||
} catch (e) {
|
||||
print('[BOT] Error disposing BackendClient: $e');
|
||||
}
|
||||
|
||||
print('[BOT] Shutdown complete');
|
||||
|
||||
// Complete the completer to allow main to exit
|
||||
if (!_shutdownCompleter.isCompleted) {
|
||||
_shutdownCompleter.complete();
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
String? _extractCodeFromText(String? rawText) {
|
||||
if (rawText == null) {
|
||||
return null;
|
||||
|
|
@ -92,6 +148,11 @@ Future<void> _handleCodeClaim({
|
|||
}
|
||||
|
||||
Future<void> _run() async {
|
||||
if (_isShuttingDown) {
|
||||
print('[BOT] Shutdown in progress, not starting bot');
|
||||
return;
|
||||
}
|
||||
|
||||
print('[BOT] Starting bot version $version');
|
||||
BackendClient? backendClient;
|
||||
TeleDart? teledart;
|
||||
|
|
@ -109,6 +170,9 @@ Future<void> _run() async {
|
|||
|
||||
final username = (await Telegram(config.botToken).getMe()).username;
|
||||
teledart = TeleDart(config.botToken, Event(username!));
|
||||
|
||||
// Store globally for shutdown handler
|
||||
_globalTeledart = teledart;
|
||||
|
||||
Future<void> notifyAdmins(String message) async {
|
||||
for (final admin in adminIds) {
|
||||
|
|
@ -126,6 +190,9 @@ Future<void> _run() async {
|
|||
backendUrl: config.backendUrl,
|
||||
apiKey: config.apiKey,
|
||||
);
|
||||
|
||||
// Store globally for shutdown handler
|
||||
_globalBackendClient = backendClient;
|
||||
|
||||
// At this point all variables are initialized and non-null
|
||||
final teledartInstance = teledart;
|
||||
|
|
@ -587,7 +654,16 @@ Future<void> _run() async {
|
|||
|
||||
teledartInstance.start();
|
||||
print('[BOT] Bot started successfully');
|
||||
|
||||
// Wait for shutdown signal
|
||||
// The bot will run until it receives SIGTERM/SIGINT
|
||||
await _shutdownCompleter.future;
|
||||
} on Exception catch (e, s) {
|
||||
if (_isShuttingDown) {
|
||||
print('[BOT] Error during shutdown, exiting...');
|
||||
return;
|
||||
}
|
||||
|
||||
print('[BOT] ERROR: Error: $e\n$s');
|
||||
print('[BOT] Error while starting bot: $e');
|
||||
print('Stack trace: $s');
|
||||
|
|
@ -598,16 +674,17 @@ Future<void> _run() async {
|
|||
print(' - BACKEND_URL or MNEMO_BACKEND_URL (optional, default: https://api.mnemo-cards.online)');
|
||||
print(' - BOT_SHARE_DAILY_LIMIT (optional, default: 1)');
|
||||
|
||||
// Cleanup resources before restart
|
||||
// Cleanup resources
|
||||
try {
|
||||
backendClient?.dispose();
|
||||
} catch (_) {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
|
||||
print('Restarting in 5 seconds...');
|
||||
await Future.delayed(const Duration(seconds: 5));
|
||||
return _run();
|
||||
// Exit with error code instead of restarting
|
||||
// Let Docker/Coolify handle restarts with restart policy
|
||||
print('[BOT] Exiting with error code...');
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue