-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IPC API library #27
Comments
@kronolynx 's research on IPC is in #23 |
Whoever gets assigned this story will likely need to:
|
This is being worked by @mmartinbar in her |
As per latest design, API methods are implemented in the backend by exporting them inside the Those methods need to comply with the |
Common functionality for back and front ends given by IPCCommon module. Dummy handlers for a ping-pong basic test. Implemented directory-based IPC handler loading logic. witnet#27
Well-formatted ts file was not committed in previous commit witnet#27
Synchronous modelMain process implementationipcMain.on(IPC_SYNC_CHAN_NAME, async (event: any, args: any) => {
// Reconstruct request from serialized message
const syncRequest: ChanRequest = JSON.parse(args)
// Check request validity
if (!isValidChanRequest(syncRequest)) throw new Error("Malformed IPC request")
// Check if method is supported
if (syncRequest.method in methods) {
// Call matching method handler to get specific response
const responseMessage = await channels[chanReq.method](chanReq.params)
// Wrap response into a generic protocol response
const response = buildChanResponse(ChanResCode.Ok, chanReq.id, responseMessage)
} else {
// Wrap error message into a generic protocol response
const response = buildChanResponse(ChanResCode.ErrUnknownMethod, chanReq.id, `Unsupported method: ${syncRequest.method}`)
}
// Return the wrapped response
event.returnValue = response
}) Renderer process implementationNone Renderer process usage// Construct a new request
const syncRequest = buildChanRequest("ping")
// Send request and wait for response
const response = ipcRenderer.sendSync(IPC_SYNC_CHAN_NAME, syncRequest) Asynchronous modelMain process implementationipcMain.on(IPC_ASYNC_CHAN_NAME, async (event: any, args: any) => {
// Reconstruct request from serialized message
const syncRequest: ChanRequest = JSON.parse(args)
// Check request validity
if (!isValidChanRequest(syncRequest)) throw new Error("Malformed IPC request")
// Check if method is supported
if (syncRequest.method in methods) {
// Call matching method handler to get specific response
const responseMessage = await channels[chanReq.method](chanReq.params)
// Wrap response into a generic protocol response
const response = buildChanResponse(ChanResCode.Ok, chanReq.id, responseMessage)
} else {
// Wrap error message into a generic protocol response
const response = buildChanResponse(ChanResCode.ErrUnknownMethod, chanReq.id, `Unsupported method: ${syncRequest.method}`)
}
// Send the wrapped response back
sendAsyncMessage(event.sender, JSON.stringify(response))
}) Renderer process implementation// Holds promises for each pending request
const pendingRequests = {}
// Keeps a count of sent requests
let requestsCount = 0
// Creates new requests
const buildChanRequest = (method: string, params?: any): ChanRequest => {
return { id: requestsCount++, method, params }
}
// Conviniently wraps all the IPC and request/response correlation magic
const asyncSend = async (asyncRequest: ChanRequest, timeout = 5000): ChanResponse => {
// Create a promise for each message
const promise = new Promise((resolve, reject) => {
// Create the timeout and get a reference to the timer
const timer = setTimeout(() => {
const error = new Error(`Timed out after ${timeout}ms`)
error.name = "TimeoutError"
reject(error)
}, timeout)
// Store the resolver, rejecter and timer references
pendingRequests[asyncRequest.id] = [resolve, reject, timer]
})
// Send the asynchronous request
ipcRenderer.send(IPC_ASYNC_CHAN_NAME, JSON.stringify(asyncRequest))
// Return the promise
return promise
}
// Only response entry point in the renderer process
ipcRenderer.on(IPC_ASYNC_CHAN_NAME, async (event: any, args: any) => {
// Reconstruct request from serialized message
const asyncResponse: ChanResponse = JSON.parse(args)
// Check response validity
if (!isValidChanResponse(asyncResponse)) throw new Error("Malformed IPC response")
// Find request for which this is a response
if (asyncResponse.id in pendingRequests) {
const [resolve, reject, timer] = pendingRequests[asyncResponse.id]
// As we got a response, let's unset the timeout
clearTimeout(timer)
// Resolve or reject depending on success or error
if (asyncResponse.error) {
reject(asyncResponse.error)
} else {
resolve(asyncResponse.result)
}
} else {
// Ignore it? This is probably a late reponse (arrived after timing out)
}
}) Renderer process usageNaive approachconst asyncRequest: ChanRequest = buildChanRequest("ping")
const asyncResponse = await asyncSend(asyncRequest) Responsible approachconst asyncRequest: ChanRequest = buildChanRequest("ping")
asyncSend(asyncRequest)
.then((response) => {
console.log("Backend responded", response)
})
.catch((error) => {
if (error.name === "TimeoutError") {
console.error("Backend timed out", error)
} else {
console.error(error)
}
}) Using |
Well-formatted ts file was not committed in previous commit witnet#27
Well-formatted ts file was not committed in previous commit witnet#27
Implementation of functionality to send and receive async messages from front-end, with timeout handling. A bit of refactor as well. wip witnet#27
Today we had an informal yet very interesting discussion on how to test our IPC API. These were our conclusions:
|
A cleaner functional approach to get the map of method handlers witnet#27
Basic unit testing for all functions inside IPC common library witnet#27
Well-formatted ts file was not committed in previous commit witnet#27
Implementation of functionality to send and receive async messages from front-end, with timeout handling. A bit of refactor as well. wip witnet#27
A cleaner functional approach to get the map of method handlers witnet#27
Basic unit testing for all functions inside IPC common library witnet#27
IPC dependencies decoupled from front-end and back-end API libraries (though default communication is IPC). This should ease the unit testing of the libraries. witnet#27
Added unit tests for some front-end library functions. witnet#27
IPC dependencies decoupled from front-end and back-end API libraries (though default communication is IPC). This should ease the unit testing of the libraries. witnet#27
Added unit tests for some front-end library functions. witnet#27
Changes in code structure, better directory organisation, some name changes suggested by the team. Added extra checks in channel msg handling as well. Exported handlers can now be sync as well. witnet#27
Adapted IPC work to project layout defined in witnet#126 witnet#27
Well-formatted ts file was not committed in previous commit witnet#27
Implementation of functionality to send and receive async messages from front-end, with timeout handling. A bit of refactor as well. wip witnet#27
Adapted IPC work to project layout defined in witnet#126 witnet#27
Well-formatted ts file was not committed in previous commit witnet#27
Implementation of functionality to send and receive async messages from front-end, with timeout handling. A bit of refactor as well. wip witnet#27
A cleaner functional approach to get the map of method handlers witnet#27
Basic unit testing for all functions inside IPC common library witnet#27
IPC dependencies decoupled from front-end and back-end API libraries (though default communication is IPC). This should ease the unit testing of the libraries. witnet#27
Added unit tests for some front-end library functions. witnet#27
Changes in code structure, better directory organisation, some name changes suggested by the team. Added extra checks in channel msg handling as well. Exported handlers can now be sync as well. witnet#27
Adapted IPC work to project layout defined in witnet#126 witnet#27
Well-formatted ts file was not committed in previous commit witnet#27
Implementation of functionality to send and receive async messages from front-end, with timeout handling. A bit of refactor as well. wip witnet#27
Adapted IPC work to project layout defined in witnet#126 witnet#27
Well-formatted ts file was not committed in previous commit witnet#27
Implementation of functionality to send and receive async messages from front-end, with timeout handling. A bit of refactor as well. wip witnet#27
A cleaner functional approach to get the map of method handlers witnet#27
Basic unit testing for all functions inside IPC common library witnet#27
IPC dependencies decoupled from front-end and back-end API libraries (though default communication is IPC). This should ease the unit testing of the libraries. witnet#27
Added unit tests for some front-end library functions. witnet#27
Changes in code structure, better directory organisation, some name changes suggested by the team. Added extra checks in channel msg handling as well. Exported handlers can now be sync as well. witnet#27
Adapted IPC work to project layout defined in witnet#126 witnet#27
Well-formatted ts file was not committed in previous commit witnet#27
Implementation of functionality to send and receive async messages from front-end, with timeout handling. A bit of refactor as well. wip witnet#27
Adapted IPC work to project layout defined in witnet#126 witnet#27
The IPC API library is an IPC server that wraps and exposes backend methods to the frontend.
The text was updated successfully, but these errors were encountered: