@@ -4,13 +4,14 @@ import (
44 "encoding/json"
55 "errors"
66 "fmt"
7+ "github.com/nathanverse/go-concurrency-exercises/queue/internal"
8+ "github.com/nathanverse/go-concurrency-exercises/queue/tasks"
79 "github.com/pkg/profile"
810 "io"
911 "net"
1012 "sync"
11-
12- "github.com/nathanverse/go-concurrency-exercises/queue/internal"
13- "github.com/nathanverse/go-concurrency-exercises/queue/tasks"
13+ "sync/atomic"
14+ "time"
1415)
1516
1617type response struct {
@@ -19,9 +20,11 @@ type response struct {
1920 Error string `json:"error,omitempty"`
2021}
2122
23+ var waitingGoroutines int64
24+
2225// Serve listens for TCP connections and forwards incoming tasks to the queue.
2326func Serve (addr string , queue internal.IQueue , done <- chan struct {}) error {
24- defer profile .Start (profile .TraceProfile , profile .ProfilePath ("." )).Stop ()
27+ defer profile .Start (profile .MemProfile , profile .ProfilePath ("." )).Stop ()
2528
2629 listener , err := net .Listen ("tcp" , addr )
2730 if err != nil {
@@ -37,6 +40,20 @@ func Serve(addr string, queue internal.IQueue, done <-chan struct{}) error {
3740 listener .Close ()
3841 }()
3942
43+ go func () {
44+ for {
45+ select {
46+ case <- done :
47+ {
48+ break
49+ }
50+ default :
51+ time .Sleep (5 * time .Second )
52+ fmt .Println ("Goroutines count: " , atomic .LoadInt64 (& waitingGoroutines ))
53+ }
54+ }
55+ }()
56+
4057 for {
4158 conn , err := listener .Accept ()
4259 if err != nil {
@@ -58,18 +75,28 @@ func Serve(addr string, queue internal.IQueue, done <-chan struct{}) error {
5875
5976 wg .Add (1 )
6077 go func (c net.Conn ) {
61- defer wg .Done ()
78+ idx := atomic .AddInt64 (& waitingGoroutines , 1 )
79+ defer func () {
80+ wg .Done ()
81+ fmt .Printf ("Goroutine %d exits\n " , idx + 1 )
82+ atomic .AddInt64 (& waitingGoroutines , - 1 )
83+ }()
84+ fmt .Printf ("Goroutine %d accpet connection\n " , idx + 1 )
6285 handleConnection (c , queue , done )
6386 }(conn )
6487 }
6588}
6689
6790func handleConnection (conn net.Conn , queue internal.IQueue , done <- chan struct {}) {
68- defer conn .Close ()
91+ isFull := false
92+
93+ defer func () {
94+ conn .Close ()
95+ fmt .Println ("Connection closed, isFull=" , isFull )
96+ }()
6997
7098 decoder := json .NewDecoder (conn )
7199 encoder := json .NewEncoder (conn )
72-
73100 for {
74101 var task tasks.Task
75102 if err := decoder .Decode (& task ); err != nil {
@@ -84,6 +111,8 @@ func handleConnection(conn net.Conn, queue internal.IQueue, done <-chan struct{}
84111 ch , err := queue .Put (& task )
85112 if err != nil {
86113 _ = encoder .Encode (response {ID : task .Id , Error : err .Error ()})
114+ fmt .Printf ("Error putting task to queue: %s, retry \n " , err .Error ())
115+ isFull = true
87116 continue
88117 }
89118
0 commit comments