Skip to content

Instantly share code, notes, and snippets.

@markerikson
Last active February 21, 2023 07:25
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save markerikson/5203e71a69fa9dff203c9e27c3d84154 to your computer and use it in GitHub Desktop.
Save markerikson/5203e71a69fa9dff203c9e27c3d84154 to your computer and use it in GitHub Desktop.
Redux-Saga controllable long-polling loop
import { take, put, call, fork, cancel, cancelled } from 'redux-saga/effects'
import {EVENT_POLLING_START, EVENT_POLLING_STOP} from "constants/eventPolls";
import {ClientEventType} from "constants/serverEvents";
function* handleEventA(serverEvent) {
yield put({type : serverEvent.type, payload : {name : serverEvent.eventAData}});
}
function* handleEventB(serverEvent) {
yield put({type : serverEvent.type, payload : serverEvent.eventBData});
}
function* handleEventC(serverEvent) {
const {eventCData} = serverEvent;
const {field1, field2} = eventCData;
yield put({type : serverEvent.type, payload : {field1, field2}});
}
function* defaultEventHandler(serverEvent) {
console.log("Unhandled server event type: ", serverEvent.type);
}
const serverEventHandlers = {
[ClientEventType.EventA] : handleEventA,
[ClientEventType.EventB] : handleEventB,
[ClientEventType.EventC] : handleEventC,
}
function* handleServerEvent(serverEvent) {
const eventHandler = serverEventHandlers[serverEvent.type] || defaultEventHandler;
return yield eventHandler(serverEvent);
}
function* pollForEventsLoop(serverRPC) {
let lastCallSucceeded = true;
try {
while(true) {
const serverEvents = yield call(serverRPC.pollForEvents, lastCallSucceeded);
yield serverEvents.map(handleServerEvent);
}
}
finally {
if (yield cancelled()) {
console.log("Event poll loop cancelled");
}
console.log("Event poll loop ended");
}
}
export default function* pollForEventsDriver(serverAPI) {
const {serverRPC} = serverAPI;
while ( yield take(EVENT_POLLING_START) ) {
// starts the task in the background
const pollForEventsTask = yield fork(pollForEventsLoop, serverRPC);
// wait for the user stop action
yield take(EVENT_POLLING_STOP);
// user clicked stop. cancel the background task
// this will throw a SagaCancellationException into the forked bgSync task
yield cancel(pollForEventsTask);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment