MongoDB shell integration

In this post I’m planning to shed light on one technical limitation, that is important to overcome in next Robomongo versions. It is about current approach, that is used to integrate Robomongo and MongoDB shell. If we will solve this problem, many possibilities will be opened for further improvements in Robomongo.

Robomongo integrates with MongoDB shell by means of static linking. Linker produces single executable file with both Robomongo and shell inside it. Below is overly simplified memory layout of running Robomongo process.

As you can see, heap and data segments are shared between Robomongo and MongoDB shell. Stack is actually not shared, because Robomongo executes shells in a separate threads, and each thread in a process gets its own stack.

There are several limitations of such Robomongo design. Most of them are consequences of the fact, that MongoDB shell wasn’t designed for embedding in a strict sense. MongoDB shell is designed to be executed as a single instance inside single process. It wasn’t designed to support multiple shells (or scopes) inside one mongo tool. Here I’m speaking only about the shell, not MongoDB database itself. This is not a problem or limitation of MongoDB shell, because such constraints are by design — if you want to have a second shell, type mongo in another terminal. Nevertheless, it is problem for Robomongo, at least for the current method of integration.

Here are the practical limits of the current Robomongo design:

  1. MongoDB shell instances are not isolated from Robomongo process.
    Because of the shared address space, critical errors in MongoDB shell will crash Robomongo.
  2. MongoDB shell instances are not isolated from each other.
    Because of the shared address space and usage of global state in MongoDB shell, we do not have a strict isolation between shell instances. Acceptable level of isolation currently achieved by the means of mutual exclusion: no two concurrent threads are executing MongoDB shell code at the same time.
  3. Parallel execution of MongoDB shell instances is not possible.
    Although Robomongo allows you to work with multiple shell instances (tabs in UI), but it doesn’t allow you to execute your scripts concurrently. This is because of necessity to use mutual exclusion, mentioned in previous paragraph.
  4. Support for multiple versions of MongoDB shell is problematic.
    Although it is technically possible to dynamically load multiple versions of shared library, additional efforts should be put into careful isolation of symbols between libraries. What further complicates things, is that this should be done in a cross-platform manner, supporting different versions of dynamic linkers. Still it will not solve previously mentioned limitations, further raising complexity.
  5. Current approach will not work with different MongoDB shell technology.
    Starting from MongoDB 2.7.7, all tools (except mongo shell) have been completely rewritten in Go. It is unlikely that mongo shell will be ever rewritten in a languages other than C/C++, because of the required integration with JavaScript engines, like V8 or SpiderMonkey. But still there is a possibility of some kind of frontend for the shell, written in Go, for instance.

## Solution

Possible solution for the issues mentioned above could be a separate process for each shell. From UI perspective it means, that each newly created tab will be served by separate MongoDB shell process. Integration between Robomongo and shells could be implemented using some form of inter-process communication (IPC).

Such approach is not new and something similar is done by Chrome, where (almost) each tab is served by an engine in a separate process. They even call this a Multi-process Architecture.

This type of architecture will allows us to:

  1. Fully isolate Robomongo from shell, improving stability of application.
  2. Fully isolate shells from each other.
  3. Execute scripts on different shells in parallel. This is particularly important if you are working with long-running scripts.
  4. Support multiple versions of MongoDB shell inside one Robomongo UI.
  5. Be independent from possible (yet unlikely) changes in MongoDB shell technology.

We are planning to implement this change in Robomongo, among many others. In this blog I will write not only about 7 major features which are the first priority for us, but also about our future plans and improvements that we have prepared for Robomongo. There are a lot of them!