Skip to content

Client/server versioning for safe updates? #249

Open
@m-o-e

Description

@m-o-e

Client/server versioning

I think we need a way for the client (browser) and server to
recognize when they are running different code-versions.

@catmando describes the problem here in the context of mobile apps.

This ticket is meant to describe the same problem for the case of a plain browser/server app
because I believe the two cases (mobile vs browser/server) will need two slightly different
solutions.

Scenario

  • Browser loads the app
  • User clicks buttons, submits forms etc.
  • Server is updated while client app instances are still open. For example a model-attribute is changed from String to integer

Problems

  • Messages from the outdated clients will no longer be understood by the Server
  • Messages from the modified server will no longer be understood by the client
  • ⚠️Messages from before the update may still be enqueued in either direction.

Proposed Solution

Gladly I think/hope the solution can be relatively simple:

  • Add a version-attribute to all messages that are exchanged
  • Before processing a message either on the server- or client-side, compare the version to the locally running code-version and if they don't match:
    • Discard the message
    • Invoke an "Outdated Client"-handler on the client

The handler

By default the handler could do something simple like:

def outdated_client_handler
  if ENV == 'production'
    alert 'Your client is outdated, will refresh'
    browser.location.reload()
  else
    # Do nothing by default in development, as to
    # not interfere with hot-reloading
  end
end

It should be overridable by the developer, as most people
will want to customise the behaviour - adjust the message that is displayed, etc.

The version string

By default I would suggest to auto-generate this String at
compile-time as a hash over all files in app/*.

This should result in the outdated_client-handler to fire
whenever anything is modified.

This behaviour needs to be overridable, too, as most people
likely don't want to force their users to reload for every change.
In a production context it will often be desirable to use a manually
maintained version number instead, or to limit the hashing to
a subset of the codebase (e.g. app/model/*).

Final remarks

Thanks for reading! :)
The above is based on my (still limited) understanding of the
hyperstack-internals. I hope it can help towards a good solution
for the problem but there may be things I'm missing or better
alternative approaches. All comments & discussion welcome!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions