Advertisement
Guest User

Untitled

a guest
Feb 21st, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.60 KB | None | 0 0
  1. package main
  2. import (
  3.     "fmt"
  4.     "net/rpc"
  5.     "log"
  6.     "time"
  7.     "sync"
  8.     "math/rand"
  9.     "os"
  10.     "flag"
  11.     "strconv"
  12. )
  13.  
  14. type putStat struct {
  15.     mu sync.Mutex
  16.     successPut int
  17.     failPut int
  18. }
  19.  
  20. type getStat struct {
  21.     mu sync.Mutex
  22.     successGet int
  23.     failGet int
  24. }
  25.  
  26. type getRequest struct {
  27.     client *rpc.Client
  28.     key int
  29. }
  30.  
  31. type putRequest struct {
  32.     client *rpc.Client
  33.     key int
  34.     value string
  35. }
  36.  
  37.  // keep track of success and failure of put(key, value)
  38. func countPutStat(putInfo *putStat, isAdd bool) {
  39.     if isAdd == true {
  40.         putInfo.successPut += 1
  41.     } else {
  42.         putInfo.failPut += 1
  43.     }
  44. }
  45.  
  46. // keep track of success and failure of get(key)
  47. func countGetStat(getInfo *getStat, value string) {
  48.     if value != "" {
  49.         getInfo.successGet += 1
  50.     } else {
  51.         getInfo.failGet += 1
  52.     }
  53. }
  54.  
  55. //for now hard code the probability of get and put
  56. func getOrPut(getProb float64, putProb float64) int {
  57.     var method int
  58.     rand.Seed(time.Now().UnixNano())   
  59.     prob := rand.Float64()
  60.     if prob <= 0.4 {
  61.         method = 1 // put
  62.     } else {
  63.         method = 0 // get
  64.     }  
  65.     return method
  66. }
  67.  
  68. // poplulate getRequest struct
  69. func setGetRequest(numOp int, clients [3]*rpc.Client, getRequestInfo *getRequest) (*getRequest){
  70.     rand.Seed(time.Now().UnixNano())
  71.     key := rand.Intn(numOp)
  72.     switch node := key % 3; node { // indicate which node to fire request to by using a specific client of that node
  73.         case 0:
  74.             getRequestInfo.client = clients[0]
  75.         case 1:
  76.             getRequestInfo.client = clients[1]
  77.         case 2:
  78.             getRequestInfo.client = clients[2]
  79.     }
  80.     getRequestInfo.key = key
  81.     return getRequestInfo
  82. }
  83.  
  84. // poplulate putRequest struct
  85. func setPutRequest(numOp int, clients [3]*rpc.Client, value string, putRequestInfo *putRequest) {
  86.     rand.Seed(time.Now().UnixNano())
  87.     key := rand.Intn(numOp)
  88.     switch node := key % 3; node { // indicate which node to fire request to by using a specific client of that node
  89.         case 0:
  90.             putRequestInfo.client = clients[0]
  91.         case 1:
  92.             putRequestInfo.client = clients[1]
  93.         case 2:
  94.             putRequestInfo.client = clients[2]
  95.     }
  96.     putRequestInfo.key = key
  97.     putRequestInfo.value = value
  98. }
  99.  
  100. func put(client *rpc.Client, key int, value string, putInfo *putStat, wg *sync.WaitGroup, timeRecords chan<- time.Duration) {
  101.     defer timeTrack(time.Now(), timeRecords)
  102.     defer wg.Done()
  103.     var isAdd bool // return true if put put new (key, value)
  104.                    // return false if put update value of the already existing key
  105.     client.Call("DHT.Put", &PutArgs{key, value}, &isAdd)
  106.     putInfo.mu.Lock()
  107.     countPutStat(putInfo, isAdd)
  108.     putInfo.mu.Unlock()
  109. }
  110.  
  111. func get(client *rpc.Client, key int, getInfo *getStat, wg *sync.WaitGroup, timeRecords chan<- time.Duration) string {
  112.     defer timeTrack(time.Now(), timeRecords)
  113.     defer wg.Done()
  114.     var value string
  115.     client.Call("DHT.Get", &GetArgs{key}, &value)
  116.     getInfo.mu.Lock()
  117.     countGetStat(getInfo, value)
  118.     getInfo.mu.Unlock()
  119.     return value   
  120. }
  121.  
  122. // time each operation
  123. func timeTrack(start time.Time, timeRecords chan<- time.Duration) {
  124.     elapsed := time.Since(start)
  125.     timeRecords <- elapsed
  126. }
  127.  
  128. func getCommandLine() int {
  129.     flag.Parse()
  130.     s := flag.Arg(0)
  131.     i, err := strconv.Atoi(s)
  132.     if err != nil {
  133.         fmt.Println(err)
  134.         os.Exit(2)
  135.     }
  136.     return i
  137. }
  138.  
  139. func calLatency(durations []time.Duration, numOp float64) float64 {
  140.     var latency float64
  141.     for _, elem := range durations {
  142.         latency += elem.Seconds()
  143.     }
  144.     return latency/numOp
  145. }
  146.  
  147.  
  148. // from medium article: https://medium.com/@kpbird/golang-generate-fixed-size-random-string-dd6dbd5e63c0
  149. func RandStringRunes(n int) string {
  150.     var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
  151.     b := make([]rune, n)
  152.     for i := range b {
  153.         b[i] = letterRunes[rand.Intn(len(letterRunes))]
  154.     }
  155.     return string(b)
  156. }
  157.  
  158. func main() {
  159.     // connect to all 3 servers
  160.     client0, err := rpc.DialHTTP("tcp", "142.93.123.124" + ":5000")
  161.     client1, _ := rpc.DialHTTP("tcp", "142.93.204.111" + ":5001")
  162.     client2, _ := rpc.DialHTTP("tcp", "142.93.126.155" + ":5002")
  163.  
  164.     if err != nil {
  165.             log.Fatal("dialing:", err)
  166.     }
  167.     clients := [3]*rpc.Client{client0, client1, client2}
  168.     getRequestInfo := new(getRequest)
  169.     putRequestInfo := new(putRequest)
  170.     getInfo := new(getStat)
  171.     putInfo := new(putStat)
  172.     timeRecords := make(chan time.Duration)
  173.  
  174.     // get command line argument for number of operations
  175.     numOp := getCommandLine()
  176.     var wg sync.WaitGroup
  177.     start := time.Now()
  178.     wg.Add(numOp)
  179.     for i := 0; i < numOp; i++ {
  180.         method := getOrPut(0.6, 0.4) // 0 = get, 1 = put
  181.         if method == 0 { // get
  182.             setGetRequest(numOp, clients, getRequestInfo)
  183.             go get(getRequestInfo.client, getRequestInfo.key, getInfo, &wg, timeRecords)
  184.         } else { // put
  185.             setPutRequest(numOp, clients, RandStringRunes(20), putRequestInfo)
  186.             go put(putRequestInfo.client, putRequestInfo.key, putRequestInfo.value, putInfo, &wg, timeRecords)
  187.         }
  188.     }
  189.     wg.Wait()
  190.     elapsed := time.Since(start)
  191.     fmt.Println("The whole operation took:", elapsed.Seconds(), "s")
  192.     fmt.Println("Throughput:", float64(numOp)/elapsed.Seconds(), "operations/s")
  193.     var durations []time.Duration
  194.     for i := 0; i < numOp; i++ {
  195.         durations = append(durations, <-timeRecords)
  196.     }
  197.     var latency = calLatency(durations, float64(numOp))
  198.     fmt.Println("Latency:", latency, "s/operation")
  199.  
  200.     // print map of each server after put
  201.     var m = map[int]string{}
  202.     err = clients[0].Call("DHT.PrintDHT", 0, &m)
  203.     err = clients[1].Call("DHT.PrintDHT", 0, &m)
  204.     err = clients[2].Call("DHT.PrintDHT", 0, &m)
  205.    
  206.     fmt.Println("Get sucess:", getInfo.successGet)
  207.     fmt.Println("Get failure:", getInfo.failGet)
  208.     fmt.Println("Put success:", putInfo.successPut)
  209.     fmt.Println("Put failure:", putInfo.failPut)
  210. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement