#48 Full excetion safety and relaunch

Open
opened 8 years ago by fr33domlover · 4 comments

In some cases of error, the bot doesn't quit, which means the cron job never relaunches it. The process just keeps running, disconnected from IRC. If needed, use some MVar to indicate errors. Whatever is necessary to allow for instant reaction to an unrecoverable error. Then, instead of the cron job, I can wrap the overall main function with forever.

Another idea is to separate the network handling into its own monad transformer in the stack, instead of using all-in-one RWST. Then reconnection becomes possible without process rerun, inside the same Session and with all the state intact.

In some cases of error, the bot doesn't quit, which means the cron job never relaunches it. The process just keeps running, disconnected from IRC. If needed, use some `MVar` to indicate errors. Whatever is necessary to allow for instant reaction to an unrecoverable error. Then, instead of the cron job, I can wrap the overall main function with `forever`. Another idea is to separate the network handling into its own monad transformer in the stack, instead of using all-in-one `RWST`. Then reconnection becomes possible without process rerun, inside the same `Session` and with all the state intact.
fr33domlover commented 8 years ago
Owner

I created the monad-connect package which is a simple minimal monad transformer ConnectT wrapping the connection package. But it doesn't do any smart error handling. The intention is to wrap it.

Here's the plan: Have a ReConnectT transformer, which does the following:

  1. Send and receive data like ConnectT
  2. When trying to connect for some time (a.k.a timeout), wait for a while and try again. Possibly do exponential backoff like Weechat
  3. Have a callback to run on reconnection, so that state etc. can be refreshed as needed
  4. Have some outgoing channel for reporting events:
    • Trying to connect
    • Reached timeout, waiting
    • Successful connection
    • Disconnection occured (reported to us as an isEOFError exception?)

For a client connecting to multiple servers, there should be a separate thread for each server, each running in the ReConnectT monad.

I created the `monad-connect` package which is a simple minimal monad transformer `ConnectT` wrapping the `connection` package. But it doesn't do any smart error handling. The intention is to wrap it. Here's the plan: Have a `ReConnectT` transformer, which does the following: 1. Send and receive data like `ConnectT` 2. When trying to connect for some time (a.k.a timeout), wait for a while and try again. Possibly do exponential backoff like Weechat 3. Have a callback to run on reconnection, so that state etc. can be refreshed as needed 4. Have some outgoing channel for reporting events: - Trying to connect - Reached timeout, waiting - Successful connection - Disconnection occured (reported to us as an `isEOFError` exception?) For a client connecting to multiple servers, there should be a separate thread for each server, each running in the `ReConnectT` monad.
fr33domlover commented 8 years ago
Owner

I created the monad-connect package which is a simple minimal monad transformer ConnectT wrapping the connection package. But it doesn't do any smart error handling. The intention is to wrap it.

Here's the plan: Have a ReConnectT transformer, which does the following:

  1. Send and receive data like ConnectT
  2. When trying to connect for some time (a.k.a timeout), wait for a while and try again. Possibly do exponential backoff like Weechat
  3. Have a callback to run on reconnection, so that state etc. can be refreshed as needed
  4. Have some outgoing channel for reporting events:
    • Trying to connect
    • Reached timeout, waiting
    • Successful connection
    • Disconnection occured (reported to us as an isEOFError exception?)

For a client connecting to multiple servers, there should be a separate thread for each server, each running in the ReConnectT monad.

I created the `monad-connect` package which is a simple minimal monad transformer `ConnectT` wrapping the `connection` package. But it doesn't do any smart error handling. The intention is to wrap it. Here's the plan: Have a `ReConnectT` transformer, which does the following: 1. Send and receive data like `ConnectT` 2. When trying to connect for some time (a.k.a timeout), wait for a while and try again. Possibly do exponential backoff like Weechat 3. Have a callback to run on reconnection, so that state etc. can be refreshed as needed 4. Have some outgoing channel for reporting events: - Trying to connect - Reached timeout, waiting - Successful connection - Disconnection occured (reported to us as an `isEOFError` exception?) For a client connecting to multiple servers, there should be a separate thread for each server, each running in the `ReConnectT` monad.
fr33domlover commented 8 years ago
Owner

Sorry for the double post above, weirdness of Gogs and/or my web browser. Anyway, let's move on.

A computation of ConnectT roughly looks like this:

  1. Connect
  2. Send and receive. If error, disconnect and rethrow
  3. Disconnect if the user asked

Here's a suggestion for ReConnectT:

  1. Try to connect, report the event. If successful before timeout, jump to step 3
  2. We reached timeout. Report event, pick a new timeout, wait, go back to step 1
  3. We connected. Report the event.
  4. Send and receive. If LineTooLong error, this is a protocol logic error and just catch and return status locally. But if it's EOF, we lost the connection. Report the event, pick initial timeout, jump to step 1
  5. We didn't have errors. Disconnect if the user asked. Report event.
Sorry for the double post above, weirdness of Gogs and/or my web browser. Anyway, let's move on. A computation of `ConnectT` roughly looks like this: 1. Connect 2. Send and receive. If error, disconnect and rethrow 3. Disconnect if the user asked Here's a suggestion for `ReConnectT`: 1. Try to connect, report the event. If successful before timeout, jump to step 3 2. We reached timeout. Report event, pick a new timeout, wait, go back to step 1 3. We connected. Report the event. 4. Send and receive. If LineTooLong error, this is a protocol logic error and just catch and return status locally. But if it's EOF, we lost the connection. Report the event, pick initial timeout, jump to step 1 5. We didn't have errors. Disconnect if the user asked. Report event.
fr33domlover commented 8 years ago
Owner

I think the internal computation, i.e. the one we apply to the connection, can be of type ConnectT m a. But we can't use ConnectT as the transformer anymore. We need a new ReConnectT which basically runs ConnectT repeatedly in a loop with timeouts.

/me goes to vim, back later with results

I think the internal computation, i.e. the one we apply to the connection, can be of type `ConnectT m a`. But we can't use `ConnectT` as the transformer anymore. We need a new `ReConnectT` which basically runs `ConnectT` repeatedly in a loop with timeouts. /me goes to vim, back later with results
Sign in to join this conversation.
No Milestone
No assignee
1 Participants
Loading...
Cancel
Save
There is no content yet.