root symlink on MacOS BigSur

After upgrading my Macbook to BigSur (I skipped Catalina) my MongoDB didn’t want to start anymore. A quick inspection showed that the /data/db folder I used to have to house my db files didn’t exist anymore. BigSur has removed it 😱 but luckily I found a backup.

It appears that the root / folder on MacOS is now readonly, and I wasn’t able to copy the backup to its original place. I chose the Mac disk instead, and it now sits in /System/Volumes/Data/data

What was left is to create a symlink to /data, and the way to do that is by using the /etc/synthetic.conf file:

data    /System/Volumes/Data/data

This fixes the /data folder I used to have for MongoDB.

ESLint Config

A quick example how to configure your coding style in ESLint.

Where?

You can choose to place your configuration either in your package.json in an eslintConfig field, or an .eslintrc.js file. For ESM, yaml, or json files read here. These files will be picked up by ESLint automatically, but you can also specify a file like so:

eslint --config my_conf.json my_javascript_code.js

How?

Using rules. There are a lot of rules in ESlint, and we want to write the ones that matter to us into the conf file.

Let’s say we want to prefer using the === operator over ==, which is considered good practice and a popular topic in Javascript development. The ESLint rule for that is eqeqeq – aimed at eliminating the type-unsafe equality operators.

{
    "rules": {
        "eqeqeq": "warn"
    }
}

Possible values are off, warn, error – or respectively 0, 1, 2. Very easy. Now you might want to explore the long list of rules for ESLint to see what you need.

Inline Rules

Rules can also be defined inline:

/* eslint eqeqeq: "warn" */

This way you can overwrite a rule locally, or disable it where needed.

Pre-defined rules

It might look like a tedious job to go through all these available rules and decide if you want to throw an error, a warning, or disable them, and it can be a good idea to start off an existing style from a popular project. An often used style, for example, is the AirBnb style which can be extended by your own rules.

npm i eslint-config-airbnb

For more information read the npm instructions or follow this more comprehensive tutorial on Medium.

mutable mutexes

const member functions

If a member function does not change the object it belongs to, it should be marked as const. This does not only help the reader to easier understand the code, but also the compiler to optimize the binary. A const member function can be called on a const object. So far, so good. But what if you need to make such a method thread safe?

logical constness

Logical constness describes when it is Ok to make an object member mutable, and is thoroughly explained in the book Effective C++ by Scott Meyers. Contrary to bitwise constness, logical constness allows to modify some of the members of the object: the ones that are not important or meaningful to the logic of the class. Such members could be technical implementation details as e.g. mutexes, and we should be fine using the mutable keyword here:

class Foo {

    void doSomething() const {
        std::lock_guard<std::mutex> lock;
        readFromStructure();
    };

private:
    mutable std::mutex mutex_;
};

bitwise constness

Bitwise const is when a method doesn’t and isn’t allowed to modify any of the non-static members of the object at all. This is C++’s default behavior, and one should consider carefully which member can be made mutable.

bindService() not working on Android SDK 30 and 31

This can be fixed by adding the following code snippet to the Android Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app">
  <queries>
    <package android:name="com.example.service" />
  </queries>

  <application>
    ...
  </application>
</manifest>

In SDK 29 it was working, but in SDK 30 and 31 bindService() returned always false and did not throw any exception. The system simply couldn’t find the service, even though the service was exported using android:exported="true".