@@ -30,6 +30,8 @@ use spacetimedb_data_structures::error_stream::ErrorStream;
3030use spacetimedb_data_structures:: map:: { IntMap , IntSet } ;
3131use spacetimedb_datastore:: db_metrics:: data_size:: DATA_SIZE_METRICS ;
3232use spacetimedb_datastore:: db_metrics:: DB_METRICS ;
33+ use spacetimedb_datastore:: execution_context:: Workload ;
34+ use spacetimedb_datastore:: system_tables:: ModuleKind ;
3335use spacetimedb_datastore:: traits:: Program ;
3436use spacetimedb_durability:: { self as durability} ;
3537use spacetimedb_lib:: { AlgebraicValue , Identity , Timestamp } ;
@@ -898,7 +900,6 @@ impl Host {
898900 bsatn_rlb_pool,
899901 ..
900902 } = host_controller;
901- let on_panic = host_controller. unregister_fn ( replica_id) ;
902903 let replica_dir = data_dir. replica ( replica_id) ;
903904 let ( tx_metrics_queue, tx_metrics_recorder_task) = spawn_tx_metrics_recorder ( ) ;
904905
@@ -947,7 +948,7 @@ impl Host {
947948 ( db, clients)
948949 }
949950 } ;
950- let ( program, program_needs_init) = match db. program ( ) ? {
951+ let ( mut program, program_needs_init) = match db. program ( ) ? {
951952 // Launch module with program from existing database.
952953 Some ( program) => {
953954 info ! (
@@ -974,23 +975,89 @@ impl Host {
974975 }
975976 } ;
976977
977- let ( program, launched) = ModuleLauncher {
978- database,
979- replica_id,
980- program,
981- on_panic,
982- relational_db : Arc :: new ( db) ,
983- energy_monitor : energy_monitor. clone ( ) ,
984- module_logs : match config. storage {
985- db:: Storage :: Memory => None ,
986- db:: Storage :: Disk => Some ( replica_dir. module_logs ( ) ) ,
987- } ,
988- runtimes : runtimes. clone ( ) ,
989- core : host_controller. db_cores . take ( ) ,
990- bsatn_rlb_pool : bsatn_rlb_pool. clone ( ) ,
991- }
992- . launch_module ( )
993- . await ?;
978+ let relational_db = Arc :: new ( db) ;
979+ let ( program, launched) = match HostType :: from ( program. kind ) {
980+ HostType :: Js => {
981+ ModuleLauncher {
982+ database,
983+ replica_id,
984+ program,
985+ on_panic : host_controller. unregister_fn ( replica_id) ,
986+ relational_db,
987+ energy_monitor : energy_monitor. clone ( ) ,
988+ module_logs : match config. storage {
989+ db:: Storage :: Memory => None ,
990+ db:: Storage :: Disk => Some ( replica_dir. module_logs ( ) ) ,
991+ } ,
992+ runtimes : runtimes. clone ( ) ,
993+ core : host_controller. db_cores . take ( ) ,
994+ bsatn_rlb_pool : bsatn_rlb_pool. clone ( ) ,
995+ }
996+ . launch_module ( )
997+ . await ?
998+ }
999+ HostType :: Wasm => {
1000+ // Prior to https://github.com/clockworklabs/SpacetimeDB/pull/4549
1001+ // the host type in `st_module` was always set to wasm.
1002+ // We now correctly use the host type from the database, but the
1003+ // module may in fact be a JS module.
1004+ // So if launching it as a wasm module fails, try JS instead.
1005+ // If this succeeds, the module is definitely a JS module, so
1006+ // attempt to repair `st_module` in this case.
1007+ //
1008+ // TODO: This code should eventually be removed once all
1009+ // databases have been repaired.
1010+ let launch_wasm_result = ModuleLauncher {
1011+ database : database. clone ( ) ,
1012+ replica_id,
1013+ program : program. clone ( ) ,
1014+ on_panic : host_controller. unregister_fn ( replica_id) ,
1015+ relational_db : relational_db. clone ( ) ,
1016+ energy_monitor : energy_monitor. clone ( ) ,
1017+ module_logs : match config. storage {
1018+ db:: Storage :: Memory => None ,
1019+ db:: Storage :: Disk => Some ( replica_dir. clone ( ) . module_logs ( ) ) ,
1020+ } ,
1021+ runtimes : runtimes. clone ( ) ,
1022+ core : host_controller. db_cores . take ( ) ,
1023+ bsatn_rlb_pool : bsatn_rlb_pool. clone ( ) ,
1024+ }
1025+ . launch_module ( )
1026+ . await ;
1027+ match launch_wasm_result {
1028+ Ok ( program_and_module_host) => program_and_module_host,
1029+ Err ( e) => {
1030+ warn ! ( "failed to launch wasm module, trying js: {e:#}" ) ;
1031+
1032+ program. kind = ModuleKind :: JS ;
1033+ let res = ModuleLauncher {
1034+ database,
1035+ replica_id,
1036+ program : program. clone ( ) ,
1037+ on_panic : host_controller. unregister_fn ( replica_id) ,
1038+ relational_db : relational_db. clone ( ) ,
1039+ energy_monitor : energy_monitor. clone ( ) ,
1040+ module_logs : match config. storage {
1041+ db:: Storage :: Memory => None ,
1042+ db:: Storage :: Disk => Some ( replica_dir. module_logs ( ) ) ,
1043+ } ,
1044+ runtimes : runtimes. clone ( ) ,
1045+ core : host_controller. db_cores . take ( ) ,
1046+ bsatn_rlb_pool : bsatn_rlb_pool. clone ( ) ,
1047+ }
1048+ . launch_module ( )
1049+ . await ;
1050+
1051+ if res. is_ok ( ) {
1052+ let _ = relational_db
1053+ . with_auto_commit ( Workload :: Internal , |tx| relational_db. update_program ( tx, program) ) ;
1054+ }
1055+
1056+ res?
1057+ }
1058+ }
1059+ }
1060+ } ;
9941061
9951062 if program_needs_init {
9961063 let call_result = launched. module_host . init_database ( program) . await ?;
0 commit comments