diff --git a/book_with_bridge/chat/main.go b/book_with_bridge/chat/main.go new file mode 100644 index 0000000..905430f --- /dev/null +++ b/book_with_bridge/chat/main.go @@ -0,0 +1,133 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "net" + "time" +) + +type client struct { + _chan chan <- string + name string +} + + +var ( + entering = make(chan client) + leaving = make(chan client) + messages = make(chan string) + cancel = make(chan time.Time) +) + +func handleConn(conn net.Conn) { + defer conn.Close() + + ch := make(chan string) + + go clientWriter(conn,ch) + + who := conn.RemoteAddr().String() + client := client{ + _chan: ch, + name: who, + } + ch <- "You " + who + messages <- who + " connected" + entering <- client + + inputChan := make(chan string) + timeout := time.NewTimer(40*time.Second) + defer timeout.Stop() + + input := bufio.NewScanner(conn) + + go func() { + log.Println("inside of goroutine") + for input.Scan() { + log.Println("inside of Scan for loop") + inputChan <- client.name + ": " + input.Text() + } + + if err := input.Err(); err != nil { + log.Printf("Scanner error: %v", err) + } else { + log.Println("Scanner reached EOF (connection closed)") + } + + log.Println("Closing input channel") + close(inputChan) + }() + +loop: + for { + select { + case text,ok := <- inputChan: + if !ok { + leaving <- client + messages <- who + " disconnected" + break loop + } + if !timeout.Stop() { + <- timeout.C + } + timeout.Reset(40*time.Second) + messages <- text + case <- timeout.C: + ch <- "Connection timed out due to inactivity" + leaving <- client + messages <- who + " disconnected (timeout)" + break loop + } + } +} + +func clientWriter(conn net.Conn, ch <- chan string) { + for msg := range ch { + fmt.Fprintln(conn,msg) + } +} + + +func broadcaster() { + clients := make(map[client]bool) + for { + select { + case msg := <- messages: + log.Println("Got a msg") + for cli := range clients { + cli._chan <- msg + } + case cli := <- entering: + cli._chan <- "List of connected clients" + for i := range clients { + cli._chan <- i.name + } + clients[cli] = true + case cli := <- leaving: + log.Printf("Deleting client %s") + delete(clients,cli) + close(cli._chan) + } + } + +} + +func main() { + listener,err := net.Listen("tcp",":9090") + if err != nil { + log.Fatalf("Error in Lister %v",err) + } + + go broadcaster() + + for { + conn,err := listener.Accept() + if err != nil { + log.Fatalf("Error in Accept %v",err) + continue + } + go handleConn(conn) + } +} diff --git a/book_with_bridge/du/kek b/book_with_bridge/du/kek new file mode 100755 index 0000000..d17d7b6 Binary files /dev/null and b/book_with_bridge/du/kek differ diff --git a/book_with_bridge/du/main.go b/book_with_bridge/du/main.go index dcd48bf..c2220db 100644 --- a/book_with_bridge/du/main.go +++ b/book_with_bridge/du/main.go @@ -5,8 +5,12 @@ import ( "fmt" "os" "path/filepath" + "time" ) + +var verbos = flag.Bool("v",false,"show verbose") + func main() { flag.Parse() roots := flag.Args() @@ -23,13 +27,25 @@ func main() { close(fileSizes) }() - var nfiles,nbytes int64 - for size := range fileSizes { - nfiles++ - nbytes += size - } - printDU(nfiles,nbytes) + var tick <- chan time.Time + if *verbos{ + tick = time.Tick(500 * time.Millisecond) + } + var nfiles,nbytes int64 +loop: + for { + select { + case size,ok := <- fileSizes: + if !ok { + break loop + } + nfiles++ + nbytes += size + case <- tick: + printDU(nfiles,nbytes) + } + } } func printDU(nfiles, nbytes int64) { @@ -50,7 +66,6 @@ func WalkDir(dir string, fileSizes chan <- int64) { func dirents(dir string) []os.DirEntry{ entries, err := os.ReadDir(dir) - fmt.Println(entries) if err != nil { fmt.Fprintf(os.Stderr,"du1: %v\n",err) return nil