diff --git a/packages/cli/bin/cli.dart b/packages/cli/bin/cli.dart index dc863577..3b2c135f 100644 --- a/packages/cli/bin/cli.dart +++ b/packages/cli/bin/cli.dart @@ -31,7 +31,7 @@ void printRequestStats(RequestCounts requestCounts, Duration duration) { logger.info('${entry.value} ${entry.key}'); } final possible = - (duration.inSeconds * config.targetRequestsPerSecond).round(); + (duration.inSeconds * networkConfig.targetRequestsPerSecond).round(); final percent = requestCounts.total / possible; final percentString = '${(percent * 100).round()}%'; final avg = requestCounts.total / duration.inSeconds; @@ -121,8 +121,14 @@ Future cliMain(List args) async { const fs = LocalFileSystem(); final db = await defaultDatabase(); - final agentSymbol = - await db.getAgentSymbol() ?? Platform.environment['ST_AGENT']; + var agentSymbol = await db.getAgentSymbol(); + if (agentSymbol == null) { + agentSymbol = Platform.environment['ST_AGENT']; + if (agentSymbol != null) { + logger.info('Using agent symbol from environment: $agentSymbol'); + await db.setAgentSymbol(agentSymbol); + } + } if (agentSymbol == null) { throw StateError('No agent symbol found in database or environment.'); } diff --git a/packages/cli/bin/idle_queue.dart b/packages/cli/bin/idle_queue.dart index 54b2a8c5..055720f4 100644 --- a/packages/cli/bin/idle_queue.dart +++ b/packages/cli/bin/idle_queue.dart @@ -3,16 +3,22 @@ import 'dart:io'; import 'package:cli/caches.dart'; import 'package:cli/central_command.dart'; import 'package:cli/cli.dart'; -import 'package:cli/config.dart'; import 'package:cli/logic/idle_queue.dart'; import 'package:cli/net/auth.dart'; Future command(FileSystem fs, Database db, ArgResults argResults) async { final api = await defaultApi(db, getPriority: () => networkPriorityLow); - final agent = await db.getAgent(symbol: config.agentSymbol); + var agentSymbol = await db.getAgentSymbol(); + while (agentSymbol == null) { + logger.info('No agent symbol found in database, waiting 1 minute.'); + await Future.delayed(const Duration(minutes: 1)); + agentSymbol = await db.getAgentSymbol(); + } + + final agent = await db.getAgent(symbol: agentSymbol); if (agent == null) { - logger.err('Failed to load agent: ${config.agentSymbol}'); + logger.err('Failed to load agent: ${agentSymbol}'); exit(1); } final systemSymbol = agent.headquarters.system; @@ -73,5 +79,6 @@ void main(List args) async { abbr: 'a', help: 'Seed queue with all starter systems.', ), + loadConfig: false, ); } diff --git a/packages/cli/bin/network_execute.dart b/packages/cli/bin/network_execute.dart index fbf63e94..9e4d1de1 100644 --- a/packages/cli/bin/network_execute.dart +++ b/packages/cli/bin/network_execute.dart @@ -151,10 +151,10 @@ Future command(FileSystem fs, Database db, ArgResults argResults) async { final connection = await defaultDatabase(); await NetExecutor( connection, - targetRequestsPerSecond: config.targetRequestsPerSecond, + targetRequestsPerSecond: networkConfig.targetRequestsPerSecond, ).run(); } void main(List args) async { - await runOffline(args, command); + await runOffline(args, command, loadConfig: false); } diff --git a/packages/cli/bin/simulate.dart b/packages/cli/bin/simulate.dart index 1584bd0c..422ae7ab 100644 --- a/packages/cli/bin/simulate.dart +++ b/packages/cli/bin/simulate.dart @@ -196,7 +196,7 @@ Future command(FileSystem fs, Database db, ArgResults argResults) async { const extractionsPerSurvey = 10; final diamondMedianSellPrice = marketPrices.medianSellPrice(tradeSymbol)!; - final maxRequestsPerMinute = config.targetRequestsPerSecond * 60; + final maxRequestsPerMinute = networkConfig.targetRequestsPerSecond * 60; final miner = minerTransfer; final surveyor = [survey]; diff --git a/packages/cli/lib/cli.dart b/packages/cli/lib/cli.dart index f8514276..c0d6f1c4 100644 --- a/packages/cli/lib/cli.dart +++ b/packages/cli/lib/cli.dart @@ -23,6 +23,7 @@ Future runOffline( void Function(ArgParser parser)? addArgs, @visibleForTesting Logger? overrideLogger, @visibleForTesting Database? overrideDatabase, + bool loadConfig = true, }) async { final parser = ArgParser() ..addFlag( @@ -50,6 +51,9 @@ Future runOffline( return; } final db = overrideDatabase ?? await defaultDatabase(); + if (loadConfig) { + config = await Config.fromDb(db); + } final result = await fn(fs, db, results); await db.close(); return result; diff --git a/packages/cli/lib/config.dart b/packages/cli/lib/config.dart index 47b9a816..00c15d13 100644 --- a/packages/cli/lib/config.dart +++ b/packages/cli/lib/config.dart @@ -5,6 +5,16 @@ import 'package:types/types.dart'; /// This is used as a default argument and must be const. const defaultMaxAge = Duration(days: 3); +class NetworkConfig { + /// The number of requests per second allowed by the api. + /// Version 2.1 allows: + /// - 2 requests per second + /// - plus 30 requests over a 60 second burst + /// 2 * 60 + 30 = 150 requests per minute / 60 = 2.5 requests per second + /// https://docs.spacetraders.io/api-guide/rate-limits + double targetRequestsPerSecond = 2; +} + /// Class for holding our hard-coded configuration values. class Config { /// Create a new Config object. @@ -48,14 +58,6 @@ class Config { /// Used to slow down charters and have them spend less money on jumps. bool chartAsteroidsByDefault = false; - /// The number of requests per second allowed by the api. - /// Version 2.1 allows: - /// - 2 requests per second - /// - plus 30 requests over a 60 second burst - /// 2 * 60 + 30 = 150 requests per minute / 60 = 2.5 requests per second - /// https://docs.spacetraders.io/api-guide/rate-limits - double targetRequestsPerSecond = 2; - final _bootstrapShips = [ ShipType.LIGHT_HAULER, ShipType.LIGHT_HAULER, @@ -257,3 +259,6 @@ class Config { /// Our global configuration object. late Config config; + +/// Our global network configuration object. +final NetworkConfig networkConfig = NetworkConfig(); diff --git a/packages/cli/lib/logic/idle_queue.dart b/packages/cli/lib/logic/idle_queue.dart index d5ff1563..ad39eed6 100644 --- a/packages/cli/lib/logic/idle_queue.dart +++ b/packages/cli/lib/logic/idle_queue.dart @@ -186,7 +186,7 @@ class IdleQueue { Duration get minProcessingTime { // Systems make about 4 requests. return Duration( - milliseconds: (1000 * config.targetRequestsPerSecond * 4).ceil(), + milliseconds: (1000 * networkConfig.targetRequestsPerSecond * 4).ceil(), ); } diff --git a/packages/cli/lib/logic/logic.dart b/packages/cli/lib/logic/logic.dart index 42efaa91..8b4220c3 100644 --- a/packages/cli/lib/logic/logic.dart +++ b/packages/cli/lib/logic/logic.dart @@ -88,7 +88,7 @@ Future advanceShips( onComplete: (duration, requestCount, queryCounts) async { final behaviorState = await db.behaviorStateBySymbol(shipSymbol); final expectedSeconds = - (requestCount / config.targetRequestsPerSecond) * 1.2; + (requestCount / networkConfig.targetRequestsPerSecond) * 1.2; if (duration.inSeconds > expectedSeconds) { final behaviorName = behaviorState?.behavior.name; final behaviorString = @@ -160,7 +160,8 @@ class RateLimitTracker { _lastRequestCount = requestCount; final requestsPerSecond = requestsSinceLastPrint / timeSinceLastPrint.inSeconds; - final max = timeSinceLastPrint.inSeconds * config.targetRequestsPerSecond; + final max = + timeSinceLastPrint.inSeconds * networkConfig.targetRequestsPerSecond; final percent = ((requestsSinceLastPrint / max) * 100).round(); // No sense in printing low percentages, as that will just end up being // most of what we print.