owned this note
owned this note
Published
Linked with GitHub
# Week 10 Dev Update | August 12-18
I had a lot going on IRL in the last weeks. I was not able to do any meaningful progress during this time.
## What I have learned
### Libp2p
I have now a good understanding on how go-libp2p works under the hood:
- how to implement the TCP transport part.
- how the upgrade process is working; adding security and stream multiplexing to a 'raw' TCP connection
- how libp2p's Network and Host abstractions are used for, and how we could refactor both into one.
### Go concurrency
Let me start by explaining the problem I am trying to solve. Libp2p-go acts like a server, which listen on a socket and accept incoming connections; these connections are in turn 'upgraded' through a negotiation process. A lot of round-trips happens during this process, it can take a very long time if the client have connectivity issues. Waiting for the upgrade process to finish before accepting a new connection is not acceptable, so we need to parallelize this part. Hopefully, go provides goroutines and channels to solve this problem.
```go
func Listen(addr net.Addr) {
l, _ := net.Listen(addr)
for {
conn, _ := l.Accept()
upgrade(conn) // Can take a long time before returning
}
}
```
A goroutine is basically a function that is running concurrently alongside the rest of the code. It is as simple as placing the `go` keyword before the function.
```go
func Listen(addr net.Addr) {
l, _ := net.Listen(addr)
for {
conn, _ := l.Accept()
go upgrade(conn) // Returns immediately
}
}
```
We now need to find a way to collect every connection upgraded in each goroutine; we will use channels. A channel is like a FIFO queue that allow goroutines to communicate with each other. Each goroutine spawned to upgrade the connection is going to push the result in this channel.
```go
func Listen(addr net.Addr) {
conns := make(chan Conn)
l, _ := net.Listen(addr)
for {
conn, _ := l.Accept()
go func() {
upconn <- upgrade(conn) // We send the result in the channel
}
}
}
```
I am currently working on another piece of code that use `select-case` and `context`.It will be a good example to complete my explanation of go concurrency in the next weeks.
Good reads about concurrency:
[This go101.org article](https://go101.org/article/control-flows-more.html#goroutine)
[O'Reilly Concurrency in go](https://katherine.cox-buday.com/concurrency-in-go/) (DM me if you want the PDF)
## What I have done
### Design and tasks list
I have kept working on [this task list](https://hackmd.io/kZaNbHklRfOveay_DRUwfQ) so we can split the work.
In the second part of the task list, I have added design guidelines/specs for some components (Transport, Netowrk, Host). I will try to update the specs as we progress through the implementation.
### TCP Transport
Thanks to go-libp2p extensive testing suite, I was able to reuse a lot of tests and have a TDD-like approach.
I have start working on the implementation of the TCP Transport: have `Dial`, `Listen` and `Accept` to establish and accept raw TCP connections.
Then I worked on the upgrade process, to upgrade a raw TCP connection to a secured one with stream multiplexing. Securing the connection was out of scope for this task, so I have created some empty function where will be to implement it later. Same thing for the yamux multiplexer, I have added the out-of-the-box features, but I have left empty function for more complex features.
[I have opened this pull request](https://github.com/MaximeDavin/go-libp2p/pull/2) (WIP) so people can see how it is going on and suggest changes.
## What is next ?
I will finish my work on TCP transport. I really want to finish this part as soon as possible because it will unblock other component development:
- the Network component need the `Dial` and `Accept` method from the TCP Transport component.
- security upgrade with Noise
- multiplexing upgrade with yamux
I also want to write better specifications for the Network component, so I will try propose a refactoring of this component with the Host component to the rest of the team.