Crystal: Communicating between two different processes in Crystal

Created on 18 Jul 2016  路  7Comments  路  Source: crystal-lang/crystal

I'm trying to do this:
Process A -> Send
Process B <-Receive

Process B -> Send
Process A <-Receive

An example in Node.js from Stackoverflow can explain my question.

example2.js

var fork = require('child_process').fork;
var example1 = fork(__dirname + '/example1.js');

example1.on('message', function(response) {
  console.log(response);
});

example1.send({func: 'input'});

example1.js

function func(input) {
  process.send('Hello ' + input);
}

process.on('message', function(m) {
  func(m);
});

Thanks on advance!

question

Most helpful comment

This is a question for stackoverflow: using #crystal-lang, but you may use a pair of UNIX sockets:

left, right = UNIXSocket.pair

fork do
  who = right.gets
  right << "Hello #{who}"
end

left.puts "world"
puts left.gets # => "Hello world\n"

You may choose to serialize/unserialize to JSON and have a nicer API to hide the socket pair.

All 7 comments

This is a question for stackoverflow: using #crystal-lang, but you may use a pair of UNIX sockets:

left, right = UNIXSocket.pair

fork do
  who = right.gets
  right << "Hello #{who}"
end

left.puts "world"
puts left.gets # => "Hello world\n"

You may choose to serialize/unserialize to JSON and have a nicer API to hide the socket pair.

A little bit lower level, there's also the standard pipe with IO.pipe.

The example of the nodejs is async, but use pipe in Crystal is sync?

@jhass isn't IO.pipe unidirectional?

Any IO is asynchronous in Crystal even though it appears synchronous in code. There are no callbacks like in JS, but spawned fibers. Any IO operation will block the current fiber only, and let every others running.

@ysbaddaden The Stackoverflow isn't mine, is just a reference.

Ok, I look your code, and works, but how I can run from two different executables?:

Something like this?

# Process A
# right.cr
require "socket"

left, right = UNIXSocket.pair

fork do
  who = right.gets
  right << "Hello #{who}"
end
# Process B
# left.cr
require "socket"

left, right = UNIXSocket.pair

left.puts "world"
puts left.gets # => "Hello world\n"

Then I execute ./left and ./right in different terminals at the same time and nothing happens

@faustinoaq fork lanches a new process running the code inside the block. If you need it to be two executables, you can use Process.run and pass some IO to the stdin/stdout of the process. Alternatively you can use a UnixServer/UnixSocket to connect them, or even a TCPSocket. There are several alternatives, search for IPC, or "Inter-Process Communication". These techniques are valid on just about any language, Crystal included.

Ok I understand now @lbguilherme thanx for explain me, i have to research more about IPC,
@ysbaddaden sorry for my confusion and thanx for your response.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

relonger picture relonger  路  3Comments

costajob picture costajob  路  3Comments

Papierkorb picture Papierkorb  路  3Comments

will picture will  路  3Comments

asterite picture asterite  路  3Comments