Via G. Falcone 5, Pollenza (MC), Italy
+39 0733 203595

Symfony sharding

In a previous post we’ve seen how leverage Doctrine sharding functionalities. But how can we tell our app to use a specific shard?

A common web app has usually at least two sources: http requests and cli commands. Let’s see one at the time.

Http request

As you already know HTTP is a stateless protocol. It’s your responsibility to provide some sort of state between different requests. We chose to tie shard information to each user because, in our model, each user belongs only to one shard. Pay attention that “shard” and “tenant” are synonyms for us.

As the first request (usually login) comes in, Symfony uses the “default” connection (going to the global database) because we haven’t told Doctrine to go elsewhere. If login succeed a valid user is taken out the global db and his shard gets read and put into his session. This way, when a second request comes in, we know where it should go.

Symfony provides a very powerful event system you can hook into. You should set up the proper sharding connection as soon as possible, hence listening the “kernel.request” event with a high-priority listener seems to fit well.

Your listener should read sharding information from session and select the proper shard.

Here is the service config:

This way the Doctrine “default” connection will be tied to the chosen shard. However your are free to switch shard during the request lifecycle. But it’s not advisable to do such switch because it creates confusion about what shard your app is currently using. Moreover Doctrine, correctly, won’t let you switch shard during an open transaction!

Cli command

Also Symfony commands have an event system you can hook into. Listening the “console.command” event you can configure a “tenant” option for every command. This way you can invoke your command with “–shard yourShard” to target a specific shard. As already done for ShardManagerListener, the switch is always done by your ShardManager.

Some tips:

  • “shard” option is already used by “doctrine:fixtures:load” command to specify a shard connection. If we used the same name there were some problems, so we chose the “tenant” synonym.
  • it’s ok to run a command without “–shard” option. The listener returns without warning you. But you’ll point to the global database, as is the default one for the “default” connection. It’s responsibility of your specific command to check if a “–shard” option is provided or not.

Now you have a fully functional Symfony app using sharding! In the next posts we’ll dig into parallel commands for faster execution, tools for daily tasks on shards, testing environment and much more! If you like this kind of things… why not having a look of our team? We’re always looking for smart and talented people!

 

Leave a reply