…and working well, so far, in tests.
We have a geospatial SaaS platform whose public facing app is built with Meteor.
This Meteor app is fairly big, with just over 100 packages built in-house, containing over 9,500 files, over half of which are JS files. Just migrating to async
/ await
had meant prefixing 671 functions with async
, and await
-ing 2,816 function calls (the latter representing our own methods, mongo
methods, accounts-password
, etc.). This is besides the WebApp
API changes, mongo collection hooks, and having to fork locally and migrate packages while waiting for official versions (some of which we are contributing to).
Sounds like a lot of work? Depends on what you think it’s a lot. All this took us roughly 140 developer hours to do. And — this is slightly embarrassing, but we are control freaks — most of the work was done without automated scripts. But we do use an excellent IDE (WebStorm) that highlights most un-awaited methods, and we have good tests coverage.
Personally, I would say that most of the hard work was done by the people at Meteor Software, and members of the community like @zodern, @radekmie, @jkuester, @storyteller, @filipenevola and so many others. For our part, we just had to change the code according to instructions and for the most part it actually worked.
So, the strategy was simple:
-
Early on (sometimes in 2022), we migrated all methods and functions containing HTTP calls to our other services (PostgreSQL, map tiling service, data importer, catalogues, etc) to
async/await
, just as the Meteor packagehttp
got deprecated. It forced us to convert a large part of our internal API without having to even touch the collection methods. We left the latter for another time, simply because there were too many unknowns at the time regarding some community packages. -
Recently, as soon as the alpha 3.0 releases have become available, which meant we had access to new
accounts-password
andwebapp
APIs, we decided it’s time to move on with the second stage of migration. With the app on version2.14
, we migrated all the collection methods to their*Async
counterparts. This was fairly easy, since the large majority of usage was inside methods and functions we already refactored above. -
The dirty work stage. Upgraded to Meteor 3.0-beta.0 and left a minimal set of packages in the
packages
file, with the goal to at least get the app to boot.- Getting all sorts of helpful Fibers-related errors, we went and removed all instances of Fibers usage, sprinkling
async
/await
in its place. - Myriad packages constraint errors were a bit of a hair raiser. The simple way to deal with those: 1) add packages incrementally, 2) update your own
api.versionsFrom
, 3) fork locally and quickly migrate whatever you need and it is not yet migrated by the community. - Set work in batches: the
webapp
batch, theaccounts-*
batch, thebrowser-policy-content
batch, which means we went through the 3.0 changelog here and modified whatever we needed, one by one.
- Getting all sorts of helpful Fibers-related errors, we went and removed all instances of Fibers usage, sprinkling
Challenges:
-
We maintain a pretty complex accounts management system, which enables Role-based access control (RBAC), user groups, and access control lists for a variety of activities, from logging in, SSO & LDAP, to inviting users for one-off map edits and field data collection. So we had to wait until v3.0 was available so we could get on with updating everything depending on
Accounts
hooks, custom login handlers, and such. -
Some essential packages we had to fork locally and migrate:
aumel:security-authorization storyteller:cdn reywood:publish-composite meteorhacks:meteorx meteorhacks:sikka meteorhacks:inject-initial simple:json-routes meteorhacks:ssr
Some of them, particularly the
meteorhacks
ones, are quite important for a range of security and server-side black magic, so hopefully we can either 1) publish and maintain our versions, or 2) contribute the modifications to where they are being maintained. The best part is, they all have tests and they all pass after the latest updates :-). The not so good part is that in some cases, the test coverage simply does not account for new behaviour, so I’m sure we have some blind spots in there.
There are still some issues, but nothing insurmountable. All in all, this migration was scary when contemplating it early on, but quite a constructive and refreshing experience once we got our hands busy with it.