Comments (22)
I try explicitly set the broadcast IP address and now it works! @dashersw thanks a million
from cote.
sorry for the missing details. Here is the code:
time-service.js
const cote = require('cote');
const timeService = new cote.Responder({name: 'Time Service'});
timeService.on('time', (req, cb) => {
cb(new Date());
});
client.js
const cote = require('cote');
const client = new cote.Requester({name: 'Client'});
client.send({type: 'time'}, (time) => {
console.log(time);
});
from cote.
Here is what i got after run node time-service.js
Hello! I'm Time Service#b53a3d5d-91d8-417a-9d12-189ccdf70a97 on 8000
========================
and here is the ouput for client.js
Hello! I'm Client#1dbb4524-39bc-4696-b0b2-588826db86dc
========================
from cote.
you are right, actually you found the issue yourself. you can't return simple values in cote, they have to be promises.
responder.on("convert", req => req.amount * rates[`${req.from}_${req.to}`]);
will not work, it needs to be
responder.on("convert", req => Promise.resolve(req.amount * rates[`${req.from}_${req.to}`]));
from cote.
from cote.
Note: By default, every Requester will connect to every Responder it discovers, regardless of the request type. This means, every Responder should respond to the exact same set of requests, because Requesters will load-balance requests between all connected Responders regardless of their capabilities, i.e, whether or not they can handle a given request.
If you have multiple Responders with varying response handlers, you will experience lost requests. In cote, this separation between responsibilities is called segmentation, or partitioning. If you wish to segment your requests in groups, you can use keys. Check out keys for a detailed guide on how and when to use segmentation.
from cote.
@iwanjunaid "just doesn't work" is a bit too broad don't you think?
Can you share your code so we can see what you're doing?
see https://github.com/dashersw/cote-workshop for a sample work. Hope this helps
from cote.
hi @iwanjunaid ,
The sample code above works. Just make sure you run the time-service.js
first before running the client.js
so by that time, the timeservice would be available
or better yet, replace your client.js
code with
const cote = require('cote');
const client = new cote.Requester({name: 'Client'});
setInterval(()=>{
client.send({type: 'time'}, (time) => {
console.log(time);
})
}, 1000)
from cote.
In fact, you don't even need to care about the order of execution. The Requesters queue queries until a Responder is active — so you can run the client first and then the service, it will work.
@iwanjunaid this code works. could you tell us a bit more about your environment?
from cote.
@dashersw Ubuntu 16.04, node v6.10.1 and cote 0.15.1.
from cote.
Are you running in the cloud, on your local machine or a virtual machine? Are you using Docker, multiple machines, etc?
from cote.
@dashersw no, it is just a local machine on my laptop.
from cote.
Is there a way to run cote verbosely ?
from cote.
Looks like IP broadcast doesn’t work on your machine. You could try setting it up, or you could fall back to multicast, or even redis — see the readme for that.
For debugging, there’s an environment variable DEBUG that you can use, setting it to * will give everything.
from cote.
@dashersw If IP broadcast doesn't work on my machine (with macOS Mojave), how to make it work?
from cote.
@arefaslani you can try the redis fallback.
from cote.
from cote.
@matejthetree This is the responder:
// server.js
const cote = require('cote');
const responder = new cote.Responder({ name: 'currency conversion responder' });
const rates = { usd_eur: 0.91, eur_usd: 1.10 };
responder.on("convert", req => req.amount * rates[`${req.from}_${req.to}`]);
and this is the requester:
// client.js
const cote = require('cote');
const requester = new cote.Requester({ name: 'currency conversion requester' });
const request = { type: 'convert', from: 'usd', to: 'eur' };
setInterval(
async () => {
const amount = Math.ceil(Math.random() * 100);
const res = await requester.send({ ...request, amount });
console.log(`result: ${res}`);
}, 2000
)
When I run both client and server, services can't find each other by default:
But when I use Redis fallback they will find each other but nothing happens:
After using Redis fallback once, although without Redis, they will find each other sometimes but still nothing happens:
And in the end, when I return a Promise in the responder, everything works and I don't know why!
const cote = require('cote');
const responder = new cote.Responder({ name: 'currency conversion responder' });
const rates = { usd_eur: 0.91, eur_usd: 1.10 };
responder.on(
"convert",
req =>
new Promise(
(resolve, reject) => resolve(req.amount * rates[`${req.from}_${req.to}`])
)
);
I'm totally confused!
from cote.
@dashersw and @matejthetree thank you for quick response and sorry for late reply! Yesterday I was all day to what goes wrong. I've created a simple problem that looks like the original one. Suppose we have three services:
- age responder: gets year of birth as integer and calculates the age
- greeter: gets the age from age responder and listens to greet event to return a greeting message
- greeter client: sends a name to the greeter service to show the greeting message
// age responder service
const { Responder } = require("cote");
const ageResponder = new Responder({ name: "age responder" });
ageResponder.on("calculate age", req =>
Promise.resolve(new Date().getFullYear() - req.yearOfBirth)
);
// greeter service
const { Requester, Responder } = require("cote");
const ageRequester = new Requester({ name: "age requester" });
const responder = new Responder({ name: "greeter" });
(async () => {
const age = await ageRequester.send({
type: "calculate age",
yearOfBirth: 1989
});
responder.on("greet", req =>
Promise.resolve(`Hello ${req.name}! Your age is ${age} years.`)
);
})();
// greeter client service
const { Requester } = require("cote");
const requester = new Requester({ name: "greet requester" });
(async () => {
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
do {
const res = await requester.send({ type: "greet", name: "Aref" });
console.log(res);
await delay(2000);
} while (true);
})();
then I run all three services, each with a command like COTE_DISCOVERY_REDIS=true node service-file-name.js
and then services find each other but they didn't log anything! What is the problem here? How can I create a service that is at the same time a requester and a responder?
from cote.
you can read more about this here: https://github.com/dashersw/cote#keys
basically, if you don't have keys for your requesters / responders, all your responders should be able to respond to the same messages. you can't have greet
and calculate age
messages in separate responders. if that would be the case, you should segregate these services.
from cote.
@dashersw Thank you! I'll notify you about the result.
from cote.
I try explicitly set the broadcast IP address and now it works! @dashersw thanks a million
hey,
can you please share the code?
from cote.
Related Issues (20)
- No namespace and a strange "type" for Requester and Responder instances HOT 7
- Subscriber binding a socket instead of connecting (client vs server) ?
- Round-robin mechanism leads to lost requests HOT 4
- Client lost data when service graceful shutdown
- cote.js actively maintained? HOT 2
- Support specific ip addresses of instances. HOT 8
- Using cotejs on k3s cluster HOT 2
- K3S Kubernetes Cluster: TypeError [ERR_INVALID_ARG_TYPE]: The "options.port" property must be one of type number or string. Received null HOT 8
- Invalid 'main' field - node-discover HOT 2
- hiredis dependency preventing using node versions > 10? HOT 3
- [QUESTION] Are broadcasts mandatory? HOT 3
- Remove hiredis dependency HOT 3
- Discovery not working HOT 2
- How can I allow anyone over the Internet to run replicas of a service? HOT 1
- Cote not working with AWS Autoscalling instances. HOT 3
- Select port used
- Can't start cote due to port issue HOT 2
- View IP address of incoming request/broadcast HOT 1
- Hide "no listeners found for event" log HOT 2
- Requester can see the Responder but dont send request to it HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cote.