https://github.com/boisgera/go-and-distributed-systems

Go and Distributed Systems

https://github.com/boisgera/go-and-distributed-systems

Science Score: 13.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (5.5%) to scientific vocabulary
Last synced: 10 months ago · JSON representation

Repository

Go and Distributed Systems

Basic Info
  • Host: GitHub
  • Owner: boisgera
  • Language: Go
  • Default Branch: master
  • Size: 491 KB
Statistics
  • Stars: 0
  • Watchers: 2
  • Forks: 0
  • Open Issues: 0
  • Releases: 0
Created over 3 years ago · Last pushed over 3 years ago
Metadata Files
Readme

README.md

Go and Distributed Systems

HTTP Client

HTML Content

```bash $ curl http://example.org <!doctype html> Example Domain

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
    background-color: #f0f0f2;
    margin: 0;
    padding: 0;
    font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

}
div {
    width: 600px;
    margin: 5em auto;
    padding: 2em;
    background-color: #fdfdff;
    border-radius: 0.5em;
    box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
    color: #38488f;
    text-decoration: none;
}
@media (max-width: 700px) {
    div {
        margin: 0 auto;
        width: auto;
    }
}
</style>    

Example Domain

This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.

More information...

```

app.go:

```go package main

import ( "fmt" "io" "net/http" )

func main() { resp, _ := http.Get("http://example.org") bytes, _ := io.ReadAll(resp.Body) fmt.Println(string(bytes)) } ```

```bash $ go run app.go <!doctype html> Example Domain

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
    background-color: #f0f0f2;
    margin: 0;
    padding: 0;
    font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

}
div {
    width: 600px;
    margin: 5em auto;
    padding: 2em;
    background-color: #fdfdff;
    border-radius: 0.5em;
    box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
    color: #38488f;
    text-decoration: none;
}
@media (max-width: 700px) {
    div {
        margin: 0 auto;
        width: auto;
    }
}
</style>    

Example Domain

This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.

More information...

```

JSON API

Where is the ISS?

app.go

```go package main

import ( "io" "net/http" )

func PrintISSPosition() { resp, _ := http.Get("http://api.open-notify.org/iss-now.json") body := resp.Body bytes, _ := io.ReadAll(body) fmt.Println(string(bytes)) }

func main() { PrintISSPosition() } ```

$ go run app.go {"message": "success", "timestamp": 1672155304, "iss_position": {"longitude": "-13.8055", "latitude": "-37.7661"}}

If you want to make an HTTP Request and you have some additional workload, be aware that these requests take some time.

```go import ( "fmt" "time" )

...

func Compute() { for i := 1; i <= 10; i++ { time.Sleep(time.Second / 10) fmt.Print(i, " ") } fmt.Println("") }

func main() { PrintISSPosition() Compute() } ```

``` $ time go run app.go {"message": "success", "timestamp": 1672155760, "iss_position": {"longitude": "21.8250", "latitude": "-50.7057"}} 1 2 3 4 5 6 7 8 9 10

real 0m1,710s user 0m0,394s sys 0m0,125s ```

So making the request in the background with a coroutine is sensible.

```go

func main() { go PrintISSPosition() Compute() }

```

``` $ time go run app.go 1 2 3 4 {"message": "success", "timestamp": 1672156095, "iss_position": {"longitude": "54.5906", "latitude": "-49.9492"}} 5 6 7 8 9 10

real 0m1,318s user 0m0,400s sys 0m0,163s ```

The encoding/json Go package can be used to extract the relevant data from the JSON string.

```go package main

import ( "encoding/json" "fmt" "io" "net/http" )

type Position struct { Latitude string json:"latitude" Longitude string json:"longitude" }

type Wrapper struct { TimeStamp int json:"timestamp" ISSPosition Position json:"iss_position" Message string json:"message" }

func GetISSPosition() Position { resp, _ := http.Get("http://api.open-notify.org/iss-now.json") body := resp.Body bytes, _ := io.ReadAll(body) wrapper := Wrapper{} json.Unmarshal([]byte(bytes), &wrapper) return wrapper.ISSPosition }

func main() { pos := GetISSPosition() fmt.Printf("latitude: %s, longitude: %s\n", pos.Latitude, pos.Longitude) } ```

bash $ go run app.go latitude: 23.7538, longitude: -142.2912

HTTP Server

$ curl localhost:8000 curl: (7) Failed to connect to localhost port 8000: Connection refused

With a web browser

app.go

```go package main

import ( "net/http" )

func main() { http.ListenAndServe(":8000", nil) } ```

bash $ curl localhost:8000 404 page not found

With a web browser

app.go ```go package main

import ( "fmt" "net/http" "time" )

func Handler(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now()) }

func main() { http.HandleFunc("/", Handler) http.ListenAndServe(":8000", nil) } ```

bash $ go run app.go ⏳

bash $ curl localhost:8000

bash $ go run app.go 2022-12-22 12:26:33.497397732 +0100 CET m=+75.067678037 ⏳

bash $ curl localhost:8000

bash $ go run app.go 2022-12-22 12:26:33.497397732 +0100 CET m=+75.067678037 2022-12-22 12:28:16.657047211 +0100 CET m=+178.227327515 ⏳

Via a web browser

$ go run app.go 2022-12-22 12:29:17.925020503 +0100 CET m=+239.495300807 2022-12-22 12:29:18.128862112 +0100 CET m=+239.699142416 2022-12-22 12:29:18.980003382 +0100 CET m=+240.550283695 ⏳

go func main() { http.HandleFunc("/", Handler) err := http.ListenAndServe(":8000", nil) if err != nil { panic(err) } }

go $ go run app.go panic: listen tcp :8000: bind: address already in use

go func main() { http.HandleFunc("/", Handler) port := os.Getenv("PORT") if port == "" { port = "8000" } err := http.ListenAndServe(":"+port, nil) if err != nil { panic(err) } }

$ PORT=8001 go run app.go

$ curl localhost:8001

bash $ PORT=8001 go run app.go 2022-12-22 12:43:15.285093389 +0100 CET m=+4.132247194 ⏳

go func Handler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello world!\n")) }

bash $ curl localhost:8000 Hello world!

With a web browser

go func Handler(w http.ResponseWriter, r *http.Request) { html := "<p>Hello <b>world!</b></p>\n" w.Write([]byte(html)) }

bash $ curl localhost:8000 <p>Hello <b>world!</b></p>

From browser

go func Handler(w http.ResponseWriter, r *http.Request) { IPAddr := r.RemoteAddr w.Write([]byte("Hello " + IPAddr + "!\n")) }

bash $ curl localhost:8000 Hello 127.0.0.1:48358!

```go func GetIPAddr(r *http.Request) string { IPAddrPort := r.RemoteAddr if IPAddrPort == "" { panic("IP address is undefined") } IPAddr := strings.Split(IPAddrPort, ":")[0] // 🪲: very brittle return IPAddr }

func Handler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello " + GetIPAddr(r) + "!\n")) } ```

bash $ curl localhost:8000 Hello 127.0.0.1!

```go func Handler(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "plain/html") w.Write([]byte("Hello " + GetIPAddr(r) + "!\n")) }

func API(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") json := fmt.Sprintf({"ip_address": "%s"}, GetIPAddr(r)) + "\n" w.Write([]byte(json)) }

func main() { http.HandleFunc("/", Handler) http.HandleFunc("/api", API) port := os.Getenv("PORT") if port == "" { port = "8000" } err := http.ListenAndServe(":"+port, nil) if err != nil { panic(err) } } ```

```bash $ curl localhost:8000 Hello 127.0.0.1! $ curl localhost:8000\ Hello 127.0.0.1! $ curl --head localhost:8000 HTTP/1.1 200 OK Date: Thu, 22 Dec 2022 15:02:23 GMT Content-Length: 17 Content-Type: text/plain; charset=utf-8

```

```bash $ curl localhost:8000/api {"ip_address": "127.0.0.1"} $ curl --head localhost:8000/api HTTP/1.1 200 OK Content-Type: application/json Date: Thu, 22 Dec 2022 15:03:37 GMT Content-Length: 28

```

Concurrency

The HTTP server handles the requests concurrently

go func Handler(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "plain/html") w.Write([]byte("Hello " + GetIPAddr(r) + "!\n")) time.Sleep(10 * time.Second) }

bash $ curl localhost:8000 # ⏳ Wait ~10 sec Hello 127.0.0.1!

bash $ curl localhost:8000 & # Run in the background $ curl localhost:8000 & $ curl localhost:8000 & $ # ⏳ Wait ~10 sec Hello 127.0.0.1! Hello 127.0.0.1! Hello 127.0.0.1!

Query & Parameters

```go package main

import ( "fmt" "net/http" "os" )

func Handler(w http.ResponseWriter, r *http.Request) { name := r.URL.Query().Get("name") fmt.Printf("Hello %s!\n", name) }

func main() { http.HandleFunc("/", Handler) port := os.Getenv("PORT") if port == "" { port = "8000" } err := http.ListenAndServe(":"+port, nil) if err != nil { panic(err) } } ```

bash $ go run app.go ⏳

bash $ curl localhost:8000?name=Go Hello Go!

To go further

  • Python client + server: requests + FastAPI & Flask

  • Other network tools & protocols:

    • mDNS / Zeroconf
    • MQTT
    • sockets / websockets
    • webRTC

Owner

  • Name: Sébastien Boisgérault
  • Login: boisgera
  • Kind: user
  • Location: Paris, France
  • Company: Mines Paris - PSL

GitHub Events

Total
Last Year

Issues and Pull Requests

Last synced: over 1 year ago

All Time
  • Total issues: 0
  • Total pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Total issue authors: 0
  • Total pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads: unknown
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 0
proxy.golang.org: github.com/boisgera/go-and-distributed-systems
Rankings
Dependent packages count: 7.5%
Average: 8.0%
Dependent repos count: 8.4%
Last synced: about 1 year ago