Skip to content

Conversation

@joshk
Copy link
Contributor

@joshk joshk commented Oct 18, 2025

The notable changes include:

  • NervesHubLink.refresh_config() can now be used to refresh the config used by the underlying connection. Coupled with Client.ready_to_connect?(), you can provision a TPM or NervesKey, refresh the config, and then signal to the socket that it can connect.

  • Client.ready_to_connect?() can be used to delay the socket's connection until certain conditions are met, eg, wait for a device's TPM or NervesKey to be initialized. If ready_to_connect?/0 returns false, it will be checked periodically using a 5 second delay.

  • If the application config of connect: false is used, NervesHubLink.establish_connection() can be called to manually establish the connection.

  • And NervesHubLink.disconnect!() can be used to disconnect the socket and disable automatic reconnection.

A byproduct of these changes is that the Application supervisor children are always started, which allows for manual connection management.

Comment on lines +155 to +164
not Client.ready_to_connect?() ->
schedule_establish_connection_check()
{:ok, socket}

config.connect_wait_for_network ->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the assumption here that if you ever implement checks to return false on ready_to_connect?, you will skip any wait_for_network check? If I've traced things right, that seems to be the behavior

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the original intent, but I can change this, thoughts?


@impl Slipstream
def handle_cast({:refresh_config, config}, socket) do
socket = if(connected?(socket), do: disconnect(socket), else: socket)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slipstream says disconnect/1 is a no-op if it is already disconnected, so could skip the check here if so desired.

Also, if you do disconnect, do you also need to ensure the socket connects again? Since there is a new :auto_connect assigns, I'm feel like refreshing could get you into a state of being disconnected?

There is also the problem on if the Supervisor restarts the child. This only refreshes running state, but the spec stored with NervesHubLink.supervisor will still be from when it was launched. Perhaps doing the refresh outside of the socket would be more appropriate?

Supervisor.terminate_child(NervesHubLink.Supervisor, NervesHubLink.Socket)
Supervisor.delete_child(NervesHubLink.Supervisor, NervesHubLink.Socket)
Supervisor.start_child(NervesHubLink.Supervisor, {NervesHubLink.Socket, config})

Though that is aggressive. Whatever route is picked, we should probably document the warnings and precautions of it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good catch. I need to think on this a little.
I wonder if Configurator.build() should be called within the Socket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants