Fly postgres multiregion TypeORM

Hi,

I just started setting up Postgres multiregion for typeorm.

So I’m confused on how to handle the fly-replay header?

how do I detect for database read replica write errors?

I’m using TypeORM for my db calls. Also using Graphql.

I was thinking I can lisn to lisners on every “Before Insert” or “Before Update” event? this is just a thought, havnt tried it out https://typeorm.io/listeners-and-subscribers

Has anybody implemented this with typeorm?

Thanks

I haven’t but in case nobody else has either (and says how they did it) I would think you could either:

  1. have a listener on any request that might change the data. Like an insert/update/delete (as you suggest). And return a response including the fly-replay header

or

  1. listen for a database error caused by the write to a read replica. It’s not entirely clear what the recommended approach is to do that but here’s one approach:

These being the available errors:

Not sure which it would throw … I would guess a QueryFailedError as I can’t see a write-to-a-read-replica one :slight_smile:

And return a fly-replay header which Fly’s proxy will see. That should contain the region the primary database is in e.g

res.setHeader('Fly-Replay', 'region=lhr')
1 Like

OMG! Yes this is what I was looking for.

Let me give it a try. I think this is a better apporach. Just to look for errors rather than handle all write requests.

1 Like

Okay I implemnted it.

I dint use fly-replay request. TypeORM has a replication strategy here https://typeorm.io/multiple-data-sources#replication

here is a gist of my code if anybody needs for TypeORM

const databaseUrl = process.env.DATABASE_URL as string;
      let options: ConnectionOptions = {
        type: 'postgres',
        name: 'default',
        logging: false,
        synchronize: false,
        entities: [__dirname + '/../modules/**/*.js'],
        migrations: [__dirname + '/../migration/*.js'],
      };
      if (process.env.PRIMARY_REGION !== process.env.FLY_REGION) {
        options = {
          ...options,
          replication: {
            master: {
              url: databaseUrl,
            },
            slaves: [
              {
                url: databaseUrl.replace('5432', '5433'),
              },
            ],
          },
        };
      } else {
        options = {
          ...options,
          url: databaseUrl,
        };
      }
      
        return createConnection(options)

use this while you are creating a connection for produciton

1 Like