Connect to GitHub API endpoint specified by `_apicall_parameters()`,
        postprocess the result using `_apiresult_postprocess()` and trigger
        a cache update if the API call was successful.

        If an error occurs, cache the empty result generated by
        `_apiresult_error()`. Additionally, set up retrying after a certain
        time.

        Return `True` if the API call was successful, `False` otherwise.

        Call this method directly if you want to invalidate the current cache.
        Otherwise, just call `data()`, which will automatically call `update()`
        if required.

def update(self):
        """
        Connect to GitHub API endpoint specified by `_apicall_parameters()`,
        postprocess the result using `_apiresult_postprocess()` and trigger
        a cache update if the API call was successful.

        If an error occurs, cache the empty result generated by
        `_apiresult_error()`. Additionally, set up retrying after a certain
        time.

        Return `True` if the API call was successful, `False` otherwise.

        Call this method directly if you want to invalidate the current cache.
        Otherwise, just call `data()`, which will automatically call `update()`
        if required.
        """
        result = self.api.github_api(*self._apicall_parameters())
        if result is None:
            # an error occurred, try again after BACKOFF
            self._next_update = datetime.now() + timedelta(seconds=self.BACKOFF)
            # assume an empty result until the error disappears
            self._cached_result = self._apiresult_error()
        else:
            # request successful, cache does not expire
            self._next_update = None
            # Write the new result into self._cached_result to be picked up by
            # _data on `del self._data`.
            self._cached_result = self._apiresult_postprocess(result)

        # Don't `del self._data` if it has never been cached, that would create
        # ugly database entries in the cache table.
        if not self._first_lookup:
            del self._data
        else:
            self._first_lookup = False

        # signal success or error
        return result is not None