https://metaplay.io logo
Question: copy the database between develop <-> st...
# questions-and-feedback
a
Hi, I'd like to copy the game db between environments. First now from develop to stable, to get some initial data there, with matching entityIds. Later, I'd like to be able to take snapshots from prod to use develop as an environment to test new versions against the production data. What would be the simplest way to do this in the envs that Metaplay has created for us? DB backups? Or exports? I guess backups, but am not sure if I'd need to create some infra things for that, or are those already readily there as a part of the envs? I read that doc, but don't know where should put that 'module infra' conf etc. https://docs.metaplay.io/operating-a-live-game/devops/backups-and-restoring.html
the AWS backup way there seems fitting, https://docs.metaplay.io/operating-a-live-game/devops/backups-and-restoring.html#database-recovery-from-an-aws-backup-rds-snapshot but that gives an empty list for me so I guess i'd need to set it up somehow
$ aws backup list-backup-vaults
t
Hi! The documents refer more to the case of self-hosted infrastructure where it is indeed possible to seed databases using existing database snapshots (albeit this is always slightly time consuming, so mainly useful for slightly less frequent and bigger testing, e.g. load testing in a staging stack). For development environments we unfortunately are not able to support that approach (as databases for development environments are multi-tenant, so recreating from snapshots would essentially reset everything for all tenants of the database). To replicate data between development environments, the data would need to be moved on a logical level (as opposed to block level operations, as the snapshots would be). Basically this would require using 3rd party tools to take an SQL dump of the database from the source environment and then loading it up into a target environment and then restarting game servers.
If you want to give something like that a go, give me a shout and we can see if we can't set you up to be able to do the data replication. 🙂
a
ok thanks, i think it might be useful in the long run. perhaps another option would be to use the data exports & imports that you have, though. i don't know how references with IDs etc work in those. for now, i worked around the issue by adding the necessary EntityIds for the content we have to both the client and server side environment confs, so things work in the different deployments. i'm using an InitGame server function to create some entities and then put the resulting IDs to the conf for that env. for real we'll probably use the Config system to have this content, but we did not take it into use yet so this is a temp solution now, and ok as such.
n
What happens to the EntityId when you use the entity import function depends on the specific import handler for that entity kind. Players, for example, are imported with the same EntityId as they had in the old environment, but you can also overwrite an existing player with another's data from the player details page. Any references to other entities should stay intact as long as the same entities exist in the destination environment. The easiest way to know is to test it.
a
oh that's cool, i think export-import and keeping the ids will be fine for our staging setup, i'll just need to write the handling for our type but it should be simple
so is implementing export & import undocumented still? are there examples maybe? perhaps i can check how it's done for Players. I mean I'd need it for my own type now https://docs.metaplay.io/operating-a-live-game/customer-support/working-with-player-export-import.html#extending-importing-exporting-with-your-own-entity-types
n
Looks to be undocumented indeed 😅 I talked to one of our devs and he promised to write a quick "quick start guide"
A good example seems to be in
DefaultImportGuildHandler
and
DefaultExportGuildHandler
if you want to take a peek. Looks like you just need to define the export and import handlers, and then tag your entity config with a
EntityArchiveImporterExporterAttribute
Copy code
[EntityArchiveImporterExporter("myEntity", typeof(MyEntityImportHandler), typeof(MyEntityExportHandler))]
public class MyCustomEntityConfig : PersistedEntityConfig
{
    public override EntityKind        EntityKind           => EntityKindCore.MyEntity;
    public override IShardingStrategy ShardingStrategy     => ShardingStrategies.CreateStaticSharded();
}
Here's the mentioned quick start guide as well:
a
ok cool, i actually just looked for the player & guild for example and indeed it was very simply to just derive SimpleExportEntityHandler .. that config tagging thing i didn't notice will read the guide now, thanks!
now i have the codes there, but how am i supposed to use it? i mean, how can i do the export? the import in the dashboard seems to already support all kinds of archives. but only player export is in the web ui? should i add a custom dashboard button and call export myself?
n
If you have a custom dashboard page to view your entities, you can add the button there. Or just a very simple page only for exporting your entity type. You can call the
/api/entityArchive/export
api with a dictionary of the entities you want to export in the request body:
Copy code
{
  "allowExportOnFailure": false,
  "entities": {
    "myEntity": [
      "MyEntity:0000000000",
      "MyEntity:0000000002",
      "MyEntity:00000000EF"
    ]
  }
}
a
i have a custom page (or well a card in the /system page) with some other buttons, so that looks very straightforward, thanks!
hm i get an unknown error & timeout from that
/export
call, and before that i see this in the log, so maybe my entity is missing such a handler [08:37:52.645 WRN Challenge:KF6kXF7i4E] Received unknown ask from AdminApi:0000000000: PersistStateRequestRequest{ }
indeed e.g. GuildActorBase seems to have
Copy code
csharp
        [EntityAskHandler]
        async Task<PersistStateRequestResponse> HandlePersistStateRequestRequest(PersistStateRequestRequest _)
        {
            await PersistStateIntermediate();
            return PersistStateRequestResponse.Instance;
        }
yay now it executed ok!
results look good too