Frederic G. MARAND 4 years ago
parent
commit
8f7707c435
3 changed files with 59 additions and 20 deletions
  1. 12 0
      .idea/runConfigurations/Test_part_7.xml
  2. 46 19
      part7/main.go
  3. 1 1
      part7/peers_test.go

+ 12 - 0
.idea/runConfigurations/Test_part_7.xml

@@ -0,0 +1,12 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="Test part 7" type="GoTestRunConfiguration" factoryName="Go Test">
+    <module name="whispering_gophers" />
+    <working_directory value="$PROJECT_DIR$/part7" />
+    <framework value="gotest" />
+    <kind value="PACKAGE" />
+    <package value="code.osinet.fr/fgm/whispering_gophers/part7" />
+    <directory value="$PROJECT_DIR$/part7" />
+    <filePath value="$PROJECT_DIR$/" />
+    <method v="2" />
+  </configuration>
+</component>

+ 46 - 19
part7/main.go

@@ -19,12 +19,13 @@ import (
 	"os"
 	"sync"
 
-	"github.com/campoy/whispering-gophers/util"
+	"code.osinet.fr/fgm/whispering_gophers/util"
 )
 
 var (
-	peerAddr = flag.String("peer", "", "peer host:port")
-	self     string
+	listenAddr = flag.String("listen", "", "peer host:port")
+	peerAddr   = flag.String("peer", "", "peer host:port")
+	self       string
 )
 
 type Message struct {
@@ -35,7 +36,14 @@ type Message struct {
 func main() {
 	flag.Parse()
 
-	l, err := util.Listen()
+	var l net.Listener
+	var err error
+	// Create a new listener using util.Listen and put it in a variable named l.
+	if *listenAddr == "" {
+		l, err = util.ListenOnFirstUsableInterface()
+	} else {
+		l, err = net.Listen("tcp4", *listenAddr)
+	}
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -62,31 +70,49 @@ type Peers struct {
 // Add creates and returns a new channel for the given peer address.
 // If an address already exists in the registry, it returns nil.
 func (p *Peers) Add(addr string) <-chan Message {
-	// TODO: Take the write lock on p.mu. Unlock it before returning (using defer).
-
-	// TODO: Check if the address is already in the peers map under the key addr.
-	// TODO: If it is, return nil.
+	// Take the write lock on p.mu. Unlock it before returning (using defer).
+	p.mu.Lock()
+	defer p.mu.Unlock()
+
+	// Check if the address is already in the peers map under the key addr.
+	// If it is, return nil.
+	_, ok := p.m[addr]
+	if ok {
+		return nil
+	}
 
-	// TODO: Make a new channel of messages
-	// TODO: Add it to the peers map
-	// TODO: Return the newly created channel.
+	// Make a new channel of messages
+	peer := make(chan Message)
+	// Add it to the peers map
+	p.m[addr] = peer
+	// Return the newly created channel.
+	return peer
 }
 
 // Remove deletes the specified peer from the registry.
 func (p *Peers) Remove(addr string) {
-	// TODO: Take the write lock on p.mu. Unlock it before returning (using defer).
-	// TODO: Delete the peer from the peers map.
+	// Take the write lock on p.mu. Unlock it before returning (using defer).
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	// Delete the peer from the peers map.
+	delete(p.m, addr)
 }
 
 // List returns a slice of all active peer channels.
 func (p *Peers) List() []chan<- Message {
-	// TODO: Take the read lock on p.mu. Unlock it before returning (using defer).
-	// TODO: Declare a slice of chan<- Message.
-
-	for /* TODO: Iterate over the map using range */ {
-		// TODO: Append each channel into the slice.
+	// Take the read lock on p.mu. Unlock it before returning (using defer).
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	// Declare a slice of chan<- Message.
+	channels := make([]chan<- Message, 0, len(p.m))
+
+	/* Iterate over the map using range */
+	for _, v := range p.m {
+		// Append each channel into the slice.
+		channels = append(channels, v)
 	}
-	// TODO: Return the slice.
+	// Return the slice.
+	return channels
 }
 
 func serve(c net.Conn) {
@@ -117,6 +143,7 @@ func readInput() {
 	if err := s.Err(); err != nil {
 		log.Fatal(err)
 	}
+	os.Exit(0)
 }
 
 func dial(addr string) {

+ 1 - 1
part7/peers_test.go

@@ -51,7 +51,7 @@ func TestPeers(t *testing.T) {
 	select {
 	case m := <-chA:
 		if m.Body != "foo" {
-			t.Fatal("received message %q, want %q", m.Body, "foo")
+			t.Fatalf("received message %q, want %q", m.Body, "foo")
 		}
 	case <-done:
 		t.Fatal(`didn't receive message on "a" channel`)