Home

Awesome

Mailspring-Sync

This repository contains the source code for Mailspring's sync engine, a native C++11 codebase that targets Mac, Windows, and Linux. It leverages the MailCore2 IMAP/SMTP framework and uses sqlite3 to store mail data in a JSON format.

This codebase is GPLv3 licensed. You are welcome to copy, modify, and distribute this code for private or public use, but all derivative works must be open-sourced with a GPLv3 license. If you make improvements to mailsync that would benefit the upstream project, pull requests are greatly appreciated. If you have questions about licensing Mailsync or whether your use is acceptable, please email me at ben@foundry376.com.

The names of the Mailspring or Mailspring Mailsync project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

Contributing

Mailspring-Sync is entirely open-source. High-quality pull requests and contributions are welcome! When you're getting started, you may want to join our Discourse so you can ask questions and learn from other people doing development.

Contributor Covenant

Core Concepts

Each instance of Mailsync runs email, contact, and calendar sync for a single account. Mailspring runs one mailsync process for each connected email account, and automatically starts/stops/restarts them as necessary. This design means that auth failures, connection errors, etc. can simply terminate the process.

Mailsync can be run on a standard command line, which makes it easy to test separate from Mailspring. It requires an account and Mailspring ID, and these can be provided either as arguments or as newline-separated data on stdin. If you're developing in Xcode or in Visual Studio, you can configure the debugger to pass these arguments automatically so testing is easy.

When Mailsync modifies mail data, it emits all modified objects to stdout as newline-separated JSON objects. This restricts the kinds of queries that can be used to modify the database but is critical for providing data to the Mailspring UI, which is built on reactive data patterns and uses observable queries. These object changes are broadcast within the Electron app and cause observable queries backing various views to update and display new data.

Mailsync accepts "tasks" via stdin as newline-separated JSON objects. Tasks are added to a queue table in sqlite (so task completions appear as object modifications on stdout), and are divided into two parts: an immediate "local" operation and a "remote" operation that requires network access and may be retried. This design is necessary for Mailspring, because it's reactive design means no UI changes occur until the task executes "local" changes and modifies the database.

Sync Approach

Mailspring uses a fairly basic syncing algorithm, which runs on two threads with two open connections to the mail server. Within each thread, work is performed synchronously.

Sync Design Considerations

Tips

Known Issues / TODOs

Debugging on Win32

Select the project in the sidebar and view Properties => Debugging.

Put this into the command arguments field:

--identity "{\"id\":\"2137538a-6cb1-4c1f-b593-deb6103cf88b\",\"firstName\":\"Test\",\"lastName\":\"User\",\"emailAddress\":\"testuser@getmailspring.com\",\"object\":\"identity\",\"createdAt\":\"2017-09-27T19:41:39.000Z\",\"stripePlan\":\"Basic\",\"stripePlanEffective\":\"Basic\",\"stripeCustomerId\":\"XXXXX\",\"stripePeriodEnd\":\"2017-10-27T19:41:39.000Z\",\"featureUsage\":{\"snooze\":{\"quota\":15,\"period\":\"weekly\",\"usedInPeriod\":0,\"featureLimitName\":\"basic-limit\"},\"send-later\":{\"quota\":10,\"period\":\"weekly\",\"usedInPeriod\":2,\"featureLimitName\":\"basic-limit\"},\"send-reminders\":{\"quota\":10,\"period\":\"weekly\",\"usedInPeriod\":2,\"featureLimitName\":\"basic-limit\"}},\"token\":\"b7670d34-d4d4-4391-9757-a8d37f31f839\"}" --account "<your account object with .settings populated>" --mode sync

Put this into the environment field on TWO LINES and WITHOUT QUOTES:

CONFIG_DIR_PATH=C:\Users\IEUser\AppData\Roaming\Mailspring
IDENTITY_SERVER=https://id.getmailspring.com

The application does not seem to like being debugged in Debug mode. You need to use the Release configuration. This seems to be because there's a "Debug Heap" that is enabled in Debug configurations, and memory allocated by libetpan and de-allocated in mailcore2 isn't reference tracked properly.