Share memory by communicating: Channels

Fermin Blanco
3 min readNov 27, 2020

--

*Under construction

*Brainstorming *Dropping some ideas

How sweet this sounds? any idea what this means when coding?

If you are coming from a language like Javascript, this statement really does not make much sense by itself. Because the meanings we have for communication are pretty obscure on its design. What I am trying to state is that we do not think in terms of memory neither communication as a mechanism for tasks coordination.

However let’s try to match this words (communication and memory) to lines of code, so we can pictures them in coding statements. First, start hitting some network request and then try to compose an uniform response.

let googleItems = searchOnGoogle(query)
let bingItems = searchOnBing(query)
return { google: googleItems, bing: bingItems }

Of course the code above would not work because race condition are guaranteed to show (by the time the function returns neither of the request has been complete). Let’s try again

*async function
let googleItems = await searchOnGoogle(query) blocks
let bingItems = await searchOnBing(query) blocks again
return { google: googleItems, bing: bingItems }

Better but naived implemented, having into account that this code blocks the main thread. In the *previous code, each network request have to wait for the previous one to complete in order to start itself.

*async function
let [googleItems, bingItems] = await Promise.all([searchOnGoogle(query), searchOnBing(query)]) blocks
return { google: googleItems, bing: bingItems }

Concurrency is about design and it not means parallelism. Concurrency is about how to structure our code to get the most of it (in terms of performance)

The model of concurrency in Javascript is based on the event loop.

[A lot better, we could argue that there are other amazing async pattern (Observables) we could use for handling asynchronicity but that is not the point of this article.]

Since every response (http response) will come at different time, and we do not have a way a certain way to know when. We need async primitives to dealing with this uncertainty behaviour (async/await for this case).

What really matters is that in javascript we share the same address space between different tasks (probably async) to make some kind of communication. We need the resolution of task1 (searchOnGoogle) and task2 (searchOnBing) in order to compute a response. We communicate by sharing memory, so exactly the opposite we are trying to understand.

Since javascript is single thread we do not care about sharing the same address space between tasks. All access to values are safe.

Communicating by sharing memory

Coordination between access to a particular memory space (the value of a variable or return from a function) is up to us. By design the language allow us

what if we could use special type that could prevent our code to make such as mistakes?

Concurrent programming in many environments is made difficult by the subtleties required to implement correct access to shared variables. Go encourages a different approach in which shared values are passed around channels and, in fact, never actively shared by separate threads of execution. Only one goroutine has access to the value at any given time. Data races cannot occur, by design.

Channels

Of course in javascript we do not have any notion of this special type but go does.

var channel chan []byte
channel := make(chan []byte)

So every time we deal with probably concurrent tasks we could handle by sharing this allowed memory

channel <- searchOnGoogle(query)
channel <- searchOnBing(query)

that exact lines are blocking then we are nowhere on we are supposed to be. Channels by themselves are not enough to handle concurrency we have to bring upon us the so called go routines.

Go routines

Go routines are independable, isolated and non blocking operational task. So we could use them to go concurrency.

go searchOnGoogle(query)
go searchOnBing(query)

how about if we isolated our concurrent work from the one it should not be.

go func(ch chan []googleItems) {
ch <- searchOnBing(query)
}(ch)

go func(ch chan []googleItems) {
ch <- searchOnGoogle(query)
}(ch)

--

--

Fermin Blanco
Fermin Blanco

Written by Fermin Blanco

I write to fill my gaps not to show yours.

No responses yet