rearranging to channel more
This commit is contained in:
		
							parent
							
								
									5490461cd4
								
							
						
					
					
						commit
						22f0ea52e2
					
				| @ -1,7 +1,7 @@ | |||||||
| package main | package main | ||||||
| 
 | 
 | ||||||
| // Lot's of learning right out of the gate: | // TODO learn about chan chan's | ||||||
| // https://stackoverflow.com/questions/51472020/how-to-get-the-size-of-available-tcp-data | // http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/ | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|   "bufio" |   "bufio" | ||||||
| @ -23,16 +23,21 @@ import ( | |||||||
|   "gopkg.in/yaml.v2" |   "gopkg.in/yaml.v2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // I'm not sure how to pass nested structs, so I de-nested this. | ||||||
|  | // TODO: Learn if passing nested structs is desirable? | ||||||
|  | type Conf struct { | ||||||
|  |   Port uint `yaml:"port,omitempty"` | ||||||
|  |   Mailer ConfMailer | ||||||
|  | } | ||||||
| type ConfMailer struct { | type ConfMailer struct { | ||||||
|   Url string `yaml:"url,omitempty"` |   Url string `yaml:"url,omitempty"` | ||||||
|   ApiKey string `yaml:"api_key,omitempty"` |   ApiKey string `yaml:"api_key,omitempty"` | ||||||
|   From string `yaml:"from,omitempty"` |   From string `yaml:"from,omitempty"` | ||||||
| } | } | ||||||
| type Conf struct { |  | ||||||
|   Port uint `yaml:"port,omitempty"` |  | ||||||
|   Mailer ConfMailer |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | // So we can peek at net.Conn, which we can't do natively | ||||||
|  | // https://stackoverflow.com/questions/51472020/how-to-get-the-size-of-available-tcp-data | ||||||
| type bufferedConn struct { | type bufferedConn struct { | ||||||
| 	r    *bufio.Reader | 	r    *bufio.Reader | ||||||
| 	rout io.Reader | 	rout io.Reader | ||||||
| @ -58,6 +63,8 @@ func (b bufferedConn) Read(p []byte) (int, error) { | |||||||
| 	return b.r.Read(p) | 	return b.r.Read(p) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Just making these all globals right now | ||||||
|  | // because... I can clean it up later | ||||||
| type myMsg struct { | type myMsg struct { | ||||||
|   sender net.Conn |   sender net.Conn | ||||||
|   bytes []byte |   bytes []byte | ||||||
| @ -67,10 +74,14 @@ type myMsg struct { | |||||||
| 
 | 
 | ||||||
| var firstMsgs chan myMsg | var firstMsgs chan myMsg | ||||||
| var myChans map[string](chan myMsg) | var myChans map[string](chan myMsg) | ||||||
| //var myMsgs chan myMsg | var myMsgs chan myMsg | ||||||
| var myUnsortedConns map[net.Conn]bool | var myUnsortedConns map[net.Conn]bool | ||||||
| var myRawConns map[net.Conn]bool | var myRawConns map[net.Conn]bool | ||||||
| var newConns chan net.Conn | var newConns chan net.Conn | ||||||
|  | var newTcpChat chan bufferedConn | ||||||
|  | var delTcpChat chan bufferedConn | ||||||
|  | var newHttpChat chan bufferedConn | ||||||
|  | var delHttpChat chan bufferedConn | ||||||
| 
 | 
 | ||||||
| func usage() { | func usage() { | ||||||
|   fmt.Fprintf(os.Stderr, "\nusage: go run chatserver.go\n") |   fmt.Fprintf(os.Stderr, "\nusage: go run chatserver.go\n") | ||||||
| @ -115,8 +126,7 @@ func handleRaw(conn bufferedConn) { | |||||||
|       fmt.Fprintf(os.Stdout, "Ending socket\n") |       fmt.Fprintf(os.Stdout, "Ending socket\n") | ||||||
| 
 | 
 | ||||||
|       // TODO put this in a channel to prevent data races |       // TODO put this in a channel to prevent data races | ||||||
|       conn.Close(); |       delTcpChat <- conn | ||||||
|       delete(myRawConns, conn) |  | ||||||
|       break |       break | ||||||
|     } |     } | ||||||
|     buf := buffer[:count] |     buf := buffer[:count] | ||||||
| @ -160,7 +170,8 @@ func handleRaw(conn bufferedConn) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fmt.Fprintf(os.Stdout, "Queing message...\n"); |     fmt.Fprintf(os.Stdout, "Queing message...\n"); | ||||||
|     myChans["general"] <- myMsg{ |     //myChans["general"] <- myMsg{ | ||||||
|  |     myMsgs <- myMsg{ | ||||||
|       receivedAt: time.Now(), |       receivedAt: time.Now(), | ||||||
|       sender: conn, |       sender: conn, | ||||||
|       bytes: buf[0:count], |       bytes: buf[0:count], | ||||||
| @ -207,7 +218,8 @@ func handleSorted(conn bufferedConn) { | |||||||
|       // fmt.Fprintf(os.Stdout, "Weird") |       // fmt.Fprintf(os.Stdout, "Weird") | ||||||
|       continue |       continue | ||||||
|     } |     } | ||||||
|     myChans["general"] <- myMsg{ |     //myChans["general"] <- myMsg{ | ||||||
|  |     myMsgs <- myMsg{ | ||||||
|       receivedAt: time.Now(), |       receivedAt: time.Now(), | ||||||
|       sender: conn, |       sender: conn, | ||||||
|       bytes: buf[0:count], |       bytes: buf[0:count], | ||||||
| @ -241,11 +253,10 @@ func handleConnection(netConn net.Conn) { | |||||||
|     m.Lock(); |     m.Lock(); | ||||||
|     if virgin { |     if virgin { | ||||||
|       virgin = false |       virgin = false | ||||||
|       go handleSorted(bufConn) |       newHttpChat <- bufConn | ||||||
|     } else { |     } else { | ||||||
|       // TODO probably needs to go into a channel |       // TODO probably needs to go into a channel | ||||||
|       myRawConns[bufConn] = true |       newTcpChat <- bufConn | ||||||
|       go handleRaw(bufConn) |  | ||||||
|     } |     } | ||||||
|     m.Unlock(); |     m.Unlock(); | ||||||
|   }() |   }() | ||||||
| @ -327,15 +338,17 @@ func main() { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   firstMsgs = make(chan myMsg, 128) |   firstMsgs = make(chan myMsg, 128) | ||||||
|   //myMsgs = make(chan myMsg, 128) |  | ||||||
|   myChans = make(map[string](chan myMsg)) |   myChans = make(map[string](chan myMsg)) | ||||||
|   newConns = make(chan net.Conn, 128) |   newConns = make(chan net.Conn, 128) | ||||||
|  |   newTcpChat = make(chan bufferedConn, 128) | ||||||
|  |   newHttpChat = make(chan bufferedConn, 128) | ||||||
|   myRawConns = make(map[net.Conn]bool) |   myRawConns = make(map[net.Conn]bool) | ||||||
|   myUnsortedConns = make(map[net.Conn]bool) |   myUnsortedConns = make(map[net.Conn]bool) | ||||||
| 
 | 
 | ||||||
|   // TODO dynamically select on channels? |   // TODO dynamically select on channels? | ||||||
|   // https://stackoverflow.com/questions/19992334/how-to-listen-to-n-channels-dynamic-select-statement |   // https://stackoverflow.com/questions/19992334/how-to-listen-to-n-channels-dynamic-select-statement | ||||||
|   myChans["general"] = make(chan myMsg, 128) |   //myChans["general"] = make(chan myMsg, 128) | ||||||
|  |   myMsgs = make(chan myMsg, 128) | ||||||
| 
 | 
 | ||||||
|   var addr string |   var addr string | ||||||
|   if 0 != int(*port) { |   if 0 != int(*port) { | ||||||
| @ -369,8 +382,19 @@ func main() { | |||||||
|     case conn := <- newConns: |     case conn := <- newConns: | ||||||
|       ts := time.Now() |       ts := time.Now() | ||||||
|       fmt.Fprintf(os.Stdout, "[Handle New Connection] [Timestamp] %s\n", ts) |       fmt.Fprintf(os.Stdout, "[Handle New Connection] [Timestamp] %s\n", ts) | ||||||
|  |       // This is short lived | ||||||
|       go handleConnection(conn) |       go handleConnection(conn) | ||||||
|     case msg := <- myChans["general"]: |     case bufConn := <- newTcpChat: | ||||||
|  |       myRawConns[bufConn] = true | ||||||
|  |       go handleRaw(bufConn) | ||||||
|  |     case bufConn := <- newHttpChat: | ||||||
|  |       go handleSorted(bufConn) | ||||||
|  |     case bufConn := <- delHttpChat: | ||||||
|  |       bufConn.Close(); | ||||||
|  |       delete(myRawConns, bufConn) | ||||||
|  |     //case msg := <- myChans["general"]: | ||||||
|  |       //delete(myChans["general"], bufConn) | ||||||
|  |     case msg := <- myMsgs: | ||||||
|       ts, err := msg.receivedAt.MarshalJSON() |       ts, err := msg.receivedAt.MarshalJSON() | ||||||
|       if nil != err { |       if nil != err { | ||||||
|         fmt.Fprintf(os.Stderr, "[Error] %s\n", err) |         fmt.Fprintf(os.Stderr, "[Error] %s\n", err) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user