IOSched : I/O events scheduler
The iosched
module is one of the core modules of JSRE. It provides multi-channel I/O multiplexing. It can be understood as an asynchronous I/O event scheduler in JSRE. It can convert synchronous models into asynchronous mechanism.
If you like to synchronize application development, you can use iosched.select()
or other simple methods to detect I/O events, or even use blocking read and blocking write directly, just like with other synchronous languages.
User can use the following code to import the iosched
module.
var iosched = require('iosched');
Support
The following shows iosched
module APIs available for each permissions.
User Mode | Privilege Mode | |
---|---|---|
iosched.event | ● | ● |
iosched.add | ● | ● |
iosched.once | ● | ● |
iosched.remove | ● | ● |
iosched.listening | ● | ● |
iosched.fds | ● | ● |
iosched.select | ● | ● |
iosched.poll | ● | ● |
iosched.forever | ● | ● |
Iosched Object
iosched.event(method, fd, callback, errback[, arg])
method
{Integer} Event listening method.fd
{Integer} File descriptor.callback
{Function} Callback function when event occurs.arg
{Any} Argument.ioevent
{Object} ThisIoEvent
object.
errback
{Function} Callback function whencallback
return false.arg
{Any} Argument.ioevent
{Object} ThisIoEvent
object.
arg
{Any} Argument, saved in thisioevent.arg
property.- Returns: {Object} Returns the created
IoEvent
object.
Create an I/O event listener object. method
valid option as following:
Definition | Value | Description |
---|---|---|
iosched.READ | 0 | Detection event fd readable. |
iosched.WRITE | 1 | Detection event fd writable. |
iosched.EXCEPT | 2 | Detection event fd exception. |
iosched.ACCEPT | 0 | Detection event fd acceptable (alias for iosched.READ ). |
iosched.CONNECT | 1 | Detection event fd connected (alias for iosched.WRITE ). |
When the event of interest reaches, the IoEvent
object callback
will be called. If the callback
function returns false
(must be {Boolean} type), the errback
callback will be called, and then the IoEvent
object will be removed from the ioshced detect events set automatically.
Example
var buffer = new Buffer(1024);
var udp = Udp.createClient(Udp.sockaddr('192.168.1.123', 5566));
function onMessage(buffer, num) {
console.log('onMessage:', buffer.toString(num));
}
var ioevent = iosched.event(iosched.READ, udp.sockFd, () => {
var num = udp.recv(buffer);
if (num > 0) {
onMessage(buffer, num);
return true;
} else {
return false; // Remove from iosched automatically.
}
});
iosched.add(ioevent);
// Event loop
while (true) {
iosched.poll();
}
iosched.event(method, fd, callback, arg)
method
{Integer} Event listening method.fd
{Integer} File descriptor.callback
{Function} Callback function when event occurs.arg
{Any} Argument.ioevent
{Object} ThisIoEvent
object.
arg
{Any} Argument not a function, saved in thisioevent.arg
property.- Returns: {Object} Returns the created
IoEvent
object.
Create an I/O event listener object without a error callback.
Example
iosched.event(iosched.READ, fd, callback, arg);
iosched.add(ioevent)
ioevent
{Object}IoEvent
object.
Add an IoEvent
to the iosched detect events set. ioevent
must be the return value of iosched.event()
.
Example
iosched.add(ioevent);
iosched.once(ioevent)
ioevent
{Object}IoEvent
object.
Add an IoEvent
to the iosched detect events set. ioevent
must be the return value of iosched.event()
.
When the event of interest reaches, the IoEvent
object callback
will be called. If the callback
function returns false, the errback
callback will be called. This IoEvent
object will be removed from the iosched detect events set, no matter what the callback
returns.
Example
// ioevent.callback run only once when event arrives.
iosched.once(ioevent);
iosched.remove([ioevent])
ioevent
{Object}IoEvent
object. default: remove all.
Delete the specified IoEvent
object from iosched detect events set. If no IoEvent
object is specified, delete all IoEvent
objects.
Example
iosched.remove(ioevent);
iosched.remove(); // Remove all
iosched.listening(ioevent)
ioevent
{Object}IoEvent
object.- Returns: {Boolean} Whether the specified
IoEvent
object is listening.
Gets whether the specified IoEvent
object is listening. This method is available in EdgerOS 1.9.0 and later.
iosched.fds([fdsUser])
[This function is deprecated]
fdsUser
{Array} User File descriptors array. default: undefined.- Returns: {Array} Merged file descriptor set array.
The iosched.fds()
parameter and the return value are both a two-dimensional array: [[], [], []] The first sub array represents read detection file descriptors, the second sub array represents write detection file descriptors, and the third sub array represents exception detection file descriptors: [[read fd array], [write fd array], [except fd array]].
This function returns the user parameters combined with the iosched probe file collection. If the call has no parameters, only the iosched probe file collection is returned.
iosched.select([fdsUser[, timeout]])
[This function is deprecated]
fdsUser
{Array} User File descriptors array. default: undefined.timeout
{Integer} Wait timeout in milliseconds. default: undefined means wait forever.- Returns: {Array} A two-dimensional array of file descriptors with valid events detected.
The iosched.select()
parameter and the return value are both a two-dimensional array: [[], [], []] The first sub array represents read detection file descriptors, the second sub array represents write detection file descriptors, and the third sub array represents exception detection file descriptors: [[read fd array], [write fd array], [except fd array]].
This function is an I/O multiplex interface that can detect multiple file events at the same time. If any event occurs, the function return immediately and returns the file descriptor array that have the event. This function has the same functionality as the UNIX compatible system select()
function.
Example
while (true) {
iosched.select();
}
Or:
Example
var fd1 = CAN-Bus fd.
var fd2 = TCP fd.
var fd3 = UDP fd.
// Add read event detect.
Array.addFd(fds[0], fd1);
Array.addFd(fds[0], fd2);
Array.addFd(fds[0], fd3);
while (true) {
var res = iosched.select(fds, 2000);
if (res === null) {
continue; // timeout.
} else if (res === undefined) {
// error!
throw new Error('iosched.select error: ' + sys.error());
} else {
if (res[0].indexOf(fd1) >= 0) {
// CAN-Bus have read event!
// Must read here.
// If read error, the file error needs to be processed.
}
if (res[0].indexOf(fd2) >= 0) {
// TCP have read event!
// Must read here.
// If read error, the file error needs to be processed.
}
if (res[0].indexOf(fd3) >= 0) {
// UDP have read event!
// Must read here.
// If read error, the file error needs to be processed.
}
}
}
iosched.poll([timeout])
timeout
{Integer} Wait timeout in milliseconds. default: undefined means wait forever.- Returns: {Array} A two-dimensional array of file descriptors with valid events detected.
Same as iosched.select(undefined, timeout)
.
Example
while (true) {
iosched.poll();
}
iosched.forever([check[, timeout]])
check
{Object | Function} Whether to exit the event loop check. default: loop forever.timeout
{Integer} Each event detection wait timeout in milliseconds. default: undefined means wait forever.
Run asynchronous event loop. If check
is an object, check.quit
is true
, this iosched.forever()
will return in the next event detection cycle. If check
is a function, check()
will be called repeatedly in each event loop, when check()
returns false
, the iosched.forever()
will returned.
Example
iosched.forever(function() {
return true; // Loop forever
});
Synchronous to asynchronous
JSRE provides a synchronous multitasking model. Like other language environments, it also provides an asynchronous processing model. You can choose any way to develop application, even in one application, depending on the characteristics of the different transactions, you can using different methods at one application.
If you are very familiar with asynchronous development, the following method here can convert synchronization to asynchronous.
Udp
Example
var EventEmitter = require('events');
var Udp = require('udp');
var udp = Udp.createClient(Udp.sockaddr('192.168.1.123', 5566));
EventEmitter.inherits(udp);
var buffer = new Buffer(1024);
udp.on('message', (buffer, num) => {
console.log('message:', buffer.toString(num));
});
var ioevent = iosched.event(iosched.READ, udp.sockFd, () => {
var num = udp.recv(buffer);
if (num > 0) {
udp.emit('message', buffer, num);
return true;
} else {
return false; // Remove from iosched automatically.
}
});
iosched.add(ioevent);
// Event loop
while (true) {
iosched.poll();
}
// Or:
iosched.forever();