Skip to content

Commit

Permalink
feat: move BehaviorState into db.
Browse files Browse the repository at this point in the history
  • Loading branch information
eseidel committed Feb 19, 2024
1 parent 6579ea1 commit 328b8a7
Show file tree
Hide file tree
Showing 23 changed files with 161 additions and 203 deletions.
7 changes: 5 additions & 2 deletions packages/cli/bin/clear_system_watchers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ void main(List<String> args) async {
}

Future<void> command(FileSystem fs, ArgResults argResults) async {
final behaviorCache = BehaviorCache.load(fs);
final db = await defaultDatabase();
final behaviorCache = await BehaviorCache.load(db);

final shipSymbols = behaviorCache.states
.where((s) => s.behavior == Behavior.systemWatcher)
Expand All @@ -19,6 +20,8 @@ Future<void> command(FileSystem fs, ArgResults argResults) async {
}
logger.info('Clearing ${shipSymbols.length} system watchers...');
for (final shipSymbol in shipSymbols) {
behaviorCache.deleteBehavior(shipSymbol);
await behaviorCache.deleteBehavior(shipSymbol);
}

await db.close();
}
5 changes: 4 additions & 1 deletion packages/cli/bin/deals_in_progress.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ String annotatedName(CostedDeal deal) {
}

Future<void> cliMain(FileSystem fs, ArgResults argResults) async {
final behaviorCache = BehaviorCache.load(fs);
final db = await defaultDatabase();
final behaviorCache = await BehaviorCache.load(db);

final states =
behaviorCache.states.where((state) => state.deal != null).toList();
Expand Down Expand Up @@ -99,6 +100,8 @@ Future<void> cliMain(FileSystem fs, ArgResults argResults) async {
'${minerHaulers.length} miner haulers: ${minerHaulers.join(', ')}',
);
}

await db.close();
}

void main(List<String> args) async {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/bin/deals_nearby.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Future<void> cliMain(FileSystem fs, ArgResults argResults) async {
);
final marketPrices = await MarketPrices.load(db);

final behaviorCache = BehaviorCache.load(fs);
final behaviorCache = await BehaviorCache.load(db);
final shipCache = ShipCache.load(fs)!;
final agentCache = await AgentCache.load(db);
final contractSnapshot = await ContractSnapshot.load(db);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/bin/earning_per_ship.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Future<void> command(FileSystem fs, ArgResults argResults) async {

final shipSymbols = (await db.uniqueShipSymbolsInTransactions()).toList()
..sort();
final behaviorCache = BehaviorCache.load(fs);
final behaviorCache = await BehaviorCache.load(db);

final shipCache = ShipCache.load(fs)!;
final idleHaulers = idleHaulerSymbols(shipCache, behaviorCache);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/bin/fleet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ bool Function(Ship) filterFromArgs(List<String> args) {
Future<void> command(FileSystem fs, ArgResults argResults) async {
final db = await defaultDatabase();
final filter = filterFromArgs(argResults.rest);
final behaviorCache = BehaviorCache.load(fs);
final behaviorCache = await BehaviorCache.load(db);
final shipCache = ShipCache.load(fs)!;

logger.info('Fleet: ${describeShips(shipCache.ships)}');
Expand Down
4 changes: 3 additions & 1 deletion packages/cli/bin/fleet_charters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ String plural(int count, String singular, [String plural = 's']) {
}

Future<void> command(FileSystem fs, ArgResults argResults) async {
final behaviorCache = BehaviorCache.load(fs);
final db = await defaultDatabase();
final behaviorCache = await BehaviorCache.load(db);
final charterStates =
behaviorCache.states.where((s) => s.behavior == Behavior.charter);
final systemsCache = SystemsCache.load(fs)!;
Expand All @@ -66,4 +67,5 @@ Future<void> command(FileSystem fs, ArgResults argResults) async {
logger.info(' enroute to $destination $destinationType in $arrival');
}
}
await db.close();
}
2 changes: 1 addition & 1 deletion packages/cli/bin/fleet_needed_mounts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:cli/cli.dart';
Future<void> command(FileSystem fs, ArgResults argResults) async {
final db = await defaultDatabase();
final shipCache = ShipCache.load(fs)!;
final behaviorCache = BehaviorCache.load(fs);
final behaviorCache = await BehaviorCache.load(db);
final marketPrices = await MarketPrices.load(db);
final centralCommand =
CentralCommand(behaviorCache: behaviorCache, shipCache: shipCache);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/bin/market_feeder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Future<void> command(FileSystem fs, ArgResults argResults) async {
sellsFuel: defaultSellsFuel(marketListings),
);

final behaviorCache = BehaviorCache.load(fs);
final behaviorCache = await BehaviorCache.load(db);

const shipType = ShipType.LIGHT_HAULER;
final ship = staticCaches.shipyardShips[shipType]!;
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/bin/system_to_chart_next.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Future<void> command(FileSystem fs, ArgResults argResults) async {
final systemConnectivity = await loadSystemConnectivity(db);

final shipCache = ShipCache.load(fs)!;
final behaviorCache = BehaviorCache.load(fs);
final behaviorCache = await BehaviorCache.load(db);
final centralCommand = CentralCommand(
shipCache: shipCache,
behaviorCache: behaviorCache,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/bin/system_watchers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Future<void> command(FileSystem fs, ArgResults argResults) async {
final marketListings = await MarketListingSnapshot.load(db);
final systemsToWatch = marketListings.systemsWithAtLeastNMarkets(5);

final behaviorCache = BehaviorCache.load(fs);
final behaviorCache = await BehaviorCache.load(db);
final systemWatcherStates =
behaviorCache.states.where((s) => s.behavior == Behavior.systemWatcher);
final systemsCache = SystemsCache.load(fs)!;
Expand Down
10 changes: 5 additions & 5 deletions packages/cli/lib/behavior/advance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Future<DateTime?> advanceShipBehavior(
);
} on JobException catch (e) {
shipErr(ship, '$e');
caches.behaviors.deleteBehavior(ship.shipSymbol);
await caches.behaviors.deleteBehavior(ship.shipSymbol);
return null;
}
if (navResult.shouldReturn()) {
Expand All @@ -115,14 +115,14 @@ Future<DateTime?> advanceShipBehavior(
);
if (state.isComplete) {
// If the behavior is complete, clear it.
caches.behaviors.deleteBehavior(ship.shipSymbol);
await caches.behaviors.deleteBehavior(ship.shipSymbol);
} else {
// Otherwise update the behavior state.
caches.behaviors.setBehavior(ship.shipSymbol, state);
await caches.behaviors.setBehavior(ship.shipSymbol, state);
}
return waitUntil;
} on JobException catch (error) {
caches.behaviors.disableBehaviorForShip(
await caches.behaviors.disableBehaviorForShip(
ship,
error.message,
error.timeout,
Expand All @@ -131,7 +131,7 @@ Future<DateTime?> advanceShipBehavior(
if (!isInsufficientCreditsException(e)) {
rethrow;
}
caches.behaviors.disableBehaviorForShip(
await caches.behaviors.disableBehaviorForShip(
ship,
'Insufficient credits: ${e.message}',
const Duration(minutes: 10),
Expand Down
7 changes: 6 additions & 1 deletion packages/cli/lib/behavior/trader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,12 @@ Future<DateTime?> acceptContractsIfNeeded(
final contracts = contractSnapshot.activeContracts;
if (contracts.isEmpty) {
final contract = await negotiateContractAndLog(
db, api, ship, shipCache, contractSnapshot);
db,
api,
ship,
shipCache,
contractSnapshot,
);
shipInfo(ship, describeExpectedContractProfit(marketPrices, contract));
return null;
}
Expand Down
73 changes: 27 additions & 46 deletions packages/cli/lib/cache/behavior_cache.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import 'package:cli/cache/json_store.dart';
import 'package:cli/logger.dart';
import 'package:cli/printing.dart';
import 'package:file/file.dart';
import 'package:db/db.dart';
import 'package:meta/meta.dart';
import 'package:types/types.dart';

typedef _Record = Map<ShipSymbol, BehaviorState>;

@immutable
class _ShipTimeout {
const _ShipTimeout(this.shipSymbol, this.behavior, this.timeout);
Expand All @@ -17,49 +14,26 @@ class _ShipTimeout {
}

/// A class to manage the behavior cache.
class BehaviorCache extends JsonStore<_Record> {
class BehaviorCache {
/// Create a new behavior cache.
BehaviorCache(
super.stateByShipSymbol, {
required super.fs,
super.path = defaultPath,
}) : super(
recordToJson: (_Record r) => r.map(
(key, value) => MapEntry(
key.toJson(),
value.toJson(),
),
),
);
BehaviorCache(Iterable<BehaviorState> stateByShipSymbol, Database db)
: _stateByShipSymbol = Map.fromEntries(
stateByShipSymbol.map((state) => MapEntry(state.shipSymbol, state)),
),
_db = db;

/// Load the cache from a file.
factory BehaviorCache.load(
FileSystem fs, {
String path = defaultPath,
}) {
final record = JsonStore.loadRecord<_Record>(
fs,
path,
(Map<String, dynamic> j) => j.map(
(key, value) => MapEntry(
ShipSymbol.fromJson(key),
BehaviorState.fromJson(value as Map<String, dynamic>),
),
),
) ??
{};
return BehaviorCache(record, fs: fs, path: path);
static Future<BehaviorCache> load(Database db) async {
final states = await db.allBehaviorStates();
return BehaviorCache(states, db);
}

final Database _db;
final Map<ShipSymbol, BehaviorState> _stateByShipSymbol;

/// Used for temporarily disabling a ship, not persisted.
final List<_ShipTimeout> _shipTimeouts = [];

/// The default path to the cache file.
static const String defaultPath = 'data/behaviors.json';

/// The behavior state for each ship.
Map<ShipSymbol, BehaviorState> get _stateByShipSymbol => record;

/// Get the list of all behavior states.
List<BehaviorState> get states => _stateByShipSymbol.values.toList();

Expand All @@ -68,15 +42,18 @@ class BehaviorCache extends JsonStore<_Record> {
_stateByShipSymbol[shipSymbol];

/// Delete the behavior state for the given ship.
void deleteBehavior(ShipSymbol shipSymbol) {
Future<void> deleteBehavior(ShipSymbol shipSymbol) async {
await _db.deleteBehaviorState(shipSymbol);
_stateByShipSymbol.remove(shipSymbol);
save();
}

/// Set the behavior state for the given ship.
void setBehavior(ShipSymbol shipSymbol, BehaviorState behaviorState) {
Future<void> setBehavior(
ShipSymbol shipSymbol,
BehaviorState behaviorState,
) async {
await _db.setBehaviorState(behaviorState);
_stateByShipSymbol[shipSymbol] = behaviorState;
save();
}

/// Check if the given behavior is disabled for the given ship.
Expand All @@ -99,7 +76,11 @@ class BehaviorCache extends JsonStore<_Record> {
}

/// Disable the given behavior for [ship] for [duration].
void disableBehaviorForShip(Ship ship, String why, Duration duration) {
Future<void> disableBehaviorForShip(
Ship ship,
String why,
Duration duration,
) async {
final shipSymbol = ship.shipSymbol;
final currentState = getBehavior(shipSymbol);
final behavior = currentState?.behavior;
Expand All @@ -114,7 +95,7 @@ class BehaviorCache extends JsonStore<_Record> {
);

if (currentState == null || currentState.behavior == behavior) {
deleteBehavior(shipSymbol);
await deleteBehavior(shipSymbol);
} else {
shipInfo(ship, 'Not deleting ${currentState.behavior} for $shipSymbol.');
}
Expand All @@ -134,7 +115,7 @@ class BehaviorCache extends JsonStore<_Record> {
return currentState;
}
final newState = await ifAbsent();
setBehavior(shipSymbol, newState);
await setBehavior(shipSymbol, newState);
return newState;
}
}
2 changes: 1 addition & 1 deletion packages/cli/lib/cache/caches.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class Caches {
final markets = MarketCache(db, api, static.tradeGoods);
// Intentionally force refresh contracts in case we've been offline.
final contracts = await fetchContracts(db, api);
final behaviors = BehaviorCache.load(fs);
final behaviors = await BehaviorCache.load(db);

final jumpGates = await JumpGateSnapshot.load(db);
final constructionSnapshot = await ConstructionSnapshot.load(db);
Expand Down
51 changes: 0 additions & 51 deletions packages/cli/lib/cache/json_store.dart

This file was deleted.

4 changes: 4 additions & 0 deletions packages/cli/test/behavior/advance_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ void main() {
when(() => caches.behaviors.putIfAbsent(shipSymbol, any()))
.thenAnswer((_) => Future.value(behaviorState));
final logger = _MockLogger();

when(() => caches.behaviors.deleteBehavior(shipSymbol))
.thenAnswer((_) async {});

final waitUntil = await runWithLogger(
logger,
() => advanceShipBehavior(
Expand Down
Loading

0 comments on commit 328b8a7

Please sign in to comment.