Programming Notes ✍️ – Telegram
Programming Notes ✍️
12 subscribers
65 photos
1 file
22 links
Download Telegram
The service discovery mechanism in Kubernetes works as follows:

Service registration:
When a service is created in Kubernetes, it is assigned a unique DNS name and IP address.

DNS resolution:
Other services within the Kubernetes cluster can resolve the DNS name of a service to obtain its corresponding IP address.

Load balancing:
When a service receives requests from other services, Kubernetes automatically load balances the traffic across the available pods that belong to that service. This ensures scalability and fault tolerance.

Service updates:
If the number of pods associated with a service changes (e.g., due to scaling or failures), Kubernetes dynamically updates the service’s DNS record to reflect the current set of available endpoints.
disaggregation cloudification orchestration openapi
vertical disaggregation, where network functions decouple software from hardware,
allowing multiple combinations to be used

• horizontal disaggregation, where established network functions are decomposed into
more granular elements and new interfaces are designed and specified
پوینتی که همیشه باید مد نظر بگیرید :‌
هیچوقت کانسپت های مهندسی نرم افزار و برنامه نویسی رو به زبان فارسی نخونید.
👍2
mux http server with rate limiter
package main

import (
"encoding/json"
"errors"
"fmt"
"github.com/gorilla/mux"
"go.uber.org/ratelimit"
"log"
"net"
"net/http"
"sync"
"time"
)

const PORT = 8080
const RATELIMIT = 2

// RateLimit middleware.
func RateLimit(rate int) func(next http.Handler) http.Handler {
var lmap sync.Map

return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
http.Error(w, fmt.Sprintf("invalid RemoteAddr: %s", err), http.StatusInternalServerError)

return
}

lif, ok := lmap.Load(host)
if !ok {
lif = ratelimit.New(rate)
}

lm, ok := lif.(ratelimit.Limiter)
if !ok {
http.Error(w, "internal middleware error: typecast failed", http.StatusInternalServerError)

return
}

log.Println("req:", r.RemoteAddr, "Rate:", rate, "Time:", time.Now())

lm.Take()
lmap.Store(host, lm)

next.ServeHTTP(w, r)
})
}
}

func getHello(w http.ResponseWriter, r *http.Request) {
var user = map[string]interface{}{
"name": "John Doe",
"age": 42,
"message": "Hello world!",
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusAccepted)
json.NewEncoder(w).Encode(user)
}

func main() {
r := mux.NewRouter()
r.Use(RateLimit(RATELIMIT))
r.HandleFunc("/api", getHello)
fmt.Printf("listening on port %d\n", PORT)
err := http.ListenAndServe(fmt.Sprintf(":%d", PORT), r)

if errors.Is(err, http.ErrServerClosed) {
log.Fatal("server closed\n")
}

if err != nil {
log.Fatal("error occurred :", err)
}
}
👍2
Note: Only the sender should close a channel, never the receiver. Sending on a closed channel will cause a panic.

Another note: Channels aren't like files; you don't usually need to close them. Closing is only necessary when the receiver must be told there are no more values coming, such as to terminate a range loop.
Atomicity: All operations in a transaction either succeed or all are rolled back.

Consistent: The database integrity constraints are valid on completion of the transaction.

Isolated: Simultaneously occurring transactions do not interfere with each other. Contentious concurrent access is moderated by the
database so that transactions appear to run sequentially.

Durable: Irrespective of hardware or software failures, the updates made by the transaction are permanent.
👍2
🔥1
🔥1
Clear dependencies
Clear syntax
Clear semantics
Composition over inheritance
Simplicity provided by the programming model (garbage collection, concurrency)
Easy tooling (the go tool, gofmt, godoc, gofix)
🔥1
Binary search using type casting an interface to []int

var numbers = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}

func binarySearch(in interface{}, target int) int {
var num = in.([]int)
left, right := 0, len(num)-1
for left <= right {
mid := left + (right-left)/2
guess := num[mid]
if target == guess {
return mid
}
if target > guess {
left = mid + 1 // the guess was too high
}
if target < guess {
right = mid - 1 // the guess was too low
}
}
return -1
}

func main() {
fmt.Println(binarySearch(numbers, 20))
}
🔥1
running simple search & binary search in diffrenet gorutines and signaling using channels :

var TIMEOUT = 2 * time.Second

var numbers = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}

func simpleSearch(input []int, target int) int {
for i := 0; i < len(input); i++ {
if input[i] == target {
return i
}
}
return 0
}

func binarySearch(in interface{}, target int) int {
var num = in.([]int)
left, right := 0, len(num)-1
for left <= right {
mid := left + (right-left)/2
guess := num[mid]
if target == guess {
return mid
}
if target > guess {
left = mid + 1 // the guess was too high
}
if target < guess {
right = mid - 1 // the guess was too low
}
}
return -1
}

func run(signal chan bool) {
var fun1 chan bool
fun1 = make(chan bool)

go func() {
timeBinary := time.Now()
fmt.Println(binarySearch(numbers, 20))
fmt.Println(time.Since(timeBinary))
fun1 <- true

}()

var fun2 chan bool
fun2 = make(chan bool)
go func() {
timeSimple := time.Now()
fmt.Println(simpleSearch(numbers, 20))
fmt.Println(time.Since(timeSimple))
time.Sleep(10 * time.Second)
fun2 <- true
}()

if <-fun1 && <-fun2 {
signal <- true
}
}

func main() {
sig := make(chan bool)
go run(sig)

fmt.Println("Welcome to the playground!")

select {
case <-sig:
fmt.Println("Runner Finished!!!")
case <-time.After(TIMEOUT):
fmt.Println("Timed out")
}
}


this proccess waits until the sig chan recive true or the time out get triggerd.
🔥1
🔥2