Coder Social home page Coder Social logo

event's Introduction

brainlife.io event service allows you to subscribe to AMQP messages through HTML5 Websocket. It relays user's JWT to event source to make sure that user has access to events published.

For example, Amaretti service publishes task events to AMQP.

{"_id":"57c4a6fafe948ddd0372e20e","status_msg":"","request_date":"2016-08-30T19:52:46.992Z","status":"requested","progress_key":"brlife.57912b0fef01633d720918cf.57c4a6fafe948ddd0372e20e","user_id":"1","config":{"source_dir":"57c4a6fafe948ddd0372e20d/download"},"instance_id":"57912b0fef01633d720918cf","service":"soichih/bl-product-nifti","name":"diff import","__v":4,"_envs":{"BL_WORKFLOW_ID":"57912b0fef01633d720918cf","BL_WORKFLOW_DIR":"/N/dc2/scratch/hayashis/brainlife/s7-workflows/57912b0fef01633d720918cf","TASK_ID":"57c4a6fafe948ddd0372e20e","TASK_DIR":"/N/dc2/scratch/hayashis/brainlife/s7-workflows/57912b0fef01633d720918cf/57c4a6fafe948ddd0372e20e","SERVICE":"soichih/bl-product-nifti","BL_SERVICE_DIR":"$HOME/.bl/services/soichih/brlife-product-nifti","PROGRESS_URL":"https://soichi7.ppa.iu.edu/api/progress/status/_brlife.57912b0fef01633d720918cf.57c4a6fafe948ddd0372e20e","test":"hello"},"resource_id":"575ee815b62439c67b693b85","create_date":"2016-08-29T21:19:54.592Z","resource_ids":["575ee815b62439c67b693b85"],"resource_deps":[],"deps":["57c4a6fafe948ddd0372e20d"]}

Client/UI Side Things

Event Streaming

On the Web UI, you can start receiving messages by connecting to this service via WebSocket.

var jwt = localStorage.getItem("jwt");
var eventws = new ReconnectingWebSocket("wss:https://brainlife.io/api/event/subscribe?jwt="+jwt);
eventws.onopen = function(e) {
    console.log("eventws connection opened.. now binding to task message");
    eventws.send(JSON.stringify({
        bind: {
            ex: "wf", key: "task."+_instance._id+".#",
        }
    }));
}
eventws.onmessage = function(e) {
    var data = JSON.parse(e.data);
    var task = data.msg;
    console.log([task._id, task.status, task.status_msg, task.next_date]);
}

Notification

You can make a request to send user a notification message when certain event occurs.

request.post({
    url: brlife_host+"/api/event/notification/",
    json: true,
    headers: {'Authorization': 'Bearer '+req.query.jwt}
    body: {
        event: "wf.task.finished",
        handler: "email",
        config: {
            task_id: "1234567abc",
            subject: "Email subject",
            message: "Hello! your workflow has completed!",
        },
    }
}, function(err, res, body) {
    cb(err, (body.status == "ok"));
});

event field specifies type of event that will trigger your notification. For now, it only supports wf.task.finished event.

  • wf.task.finished - Triggered when Amaretti Workflow service completes a task successfully. You must specify task_id in config object.

handler field specifies event handler to run when an event occurs. For now, it only has email handler

  • email - Send email to the user (who made this notification request). You must specify subject and message fields in config object.

For example, you can make the above API call when you make a request for Amaretti workflow task execution, and user will receive the email when the task is completed. You don't have to specify "to" address because it automatically looks up user's email address via brlife-auth service. The email content is not signed (yet)

Server Side Things

Amaretti's Event service relays user's JWT to event source to check to make sure user is allowed to bind to such key. It uses configured access check API URL of an event source. For example "wf" exchange maybe configured with following.

exports.event = {
    ...

    exchanges: {
        wf: function(req, key, cb) {
            request.get({
                url: brlife_host+"/api/wf/event/checkaccess/"+key,
                json: true,
                headers: {'Authorization': 'Bearer '+req.query.jwt}
            }, function(err, res, body) {
                cb(err, (body.status == "ok"));
            });
        }
    }
    
}

Above configuration tells brainlife.io event service that, it should accept request for "wf" exchange binding, and for such bind request check user's access for the exchange and specified key using Workflow service's /event/checkaccess/:key API. The URL of API and format of key are specific to each event source services. Please read the documentation for each services.

If you'd like to allow public access (no jwt) to specific exchange / key, you could configure something like following make it open to everyone.

{
    exchanges: {
        public: function(req, key, cb) {
            cb(null, true);
        }
    }
}

API DOC

Please see Amaretti API Doc for more info.

event's People

Contributors

soichih avatar anibalsolon avatar francopestilli avatar

Watchers

James Cloos avatar  avatar

event's Issues

Properly handle closed websockets

Close connections, clean channels, etc

12022-10-15T15:50:47.339010492Z Error: not opened
d2022-10-15T15:50:47.339044235Z     at WebSocket.send (/app/node_modules/ws/lib/WebSocket.js:358:18)
K2022-10-15T15:50:47.339049254Z     at /app/api/controllers/index.js:109:32
g2022-10-15T15:50:47.339052490Z     at Message.<anonymous> (/app/node_modules/amqp/lib/queue.js:209:28)
H2022-10-15T15:50:47.339055977Z     at Message.emit (node:events:527:28)
d2022-10-15T15:50:47.339059153Z     at Queue._onContent (/app/node_modules/amqp/lib/queue.js:550:25)
y2022-10-15T15:50:47.339061878Z     at AMQPParser.self.parser.onContent (/app/node_modules/amqp/lib/connection.js:142:32)
]2022-10-15T15:50:47.339065034Z     at frameEnd (/app/node_modules/amqp/lib/parser.js:101:18)
Y2022-10-15T15:50:47.339088678Z     at frame (/app/node_modules/amqp/lib/parser.js:79:14)
Z2022-10-15T15:50:47.339092545Z     at header (/app/node_modules/amqp/lib/parser.js:65:14)
]2022-10-15T15:50:47.339095841Z     at frameEnd (/app/node_modules/amqp/lib/parser.js:112:16)
62022-10-15T15:50:47.340296670Z Error: read ECONNRESET
d2022-10-15T15:50:47.340308302Z     at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
.2022-10-15T15:50:47.340311518Z   errno: -104,
52022-10-15T15:50:47.340314063Z   code: 'ECONNRESET',
12022-10-15T15:50:47.340316217Z   syscall: 'read'
!2022-10-15T15:50:47.340318511Z }

event api dies

With this

2|event    | Sat Mar 10 2018 01:25:19 GMT+0000 (UTC) - error: Error: Error: write after end
2|event    |     at Connection.<anonymous> (/app/api/server.js:67:15)
2|event    |     at emitOne (events.js:101:20)
2|event    |     at Connection.emit (events.js:188:7)
2|event    |     at emitOne (events.js:96:13)
2|event    |     at Socket.emit (events.js:188:7)
2|event    |     at writeAfterEnd (_stream_writable.js:197:10)
2|event    |     at Socket.Writable.write (_stream_writable.js:242:5)
2|event    |     at Socket.write (net.js:657:40)
2|event    |     at Connection.self.(anonymous function) [as write] (/app/node_modules/amqp/lib/connection.js:661:27)
2|event    |     at Connection._sendMethod (/app/node_modules/amqp/lib/connection.js:866:8)
2|event    |     at Queue.Channel.reconnect (/app/node_modules/amqp/lib/channel.js:31:19)
2|event    |     at Queue.Channel (/app/node_modules/amqp/lib/channel.js:22:8)
2|event    |     at new Queue (/app/node_modules/amqp/lib/queue.js:15:11)
2|event    |     at Connection.queue (/app/node_modules/amqp/lib/connection.js:344:11)
2|event    |     at /app/api/controllers/index.js:110:33
2|event    |     at Request._callback (/app/api/config/index.js:45:17)

What's really bad is that, /health will return ok when this is happening, and I won't know this issue until I notice missing event updates.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.