Last active
October 19, 2016 11:43
-
-
Save penguinpowernz/e8a892db0538ac44d6f56a489dce3768 to your computer and use it in GitHub Desktop.
Semaphore server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"net/http" | |
"time" | |
) | |
type empty struct{} | |
type semaphore chan empty | |
// acquire n resources | |
func (s semaphore) P(n int) { | |
e := empty{} | |
for i := 0; i < n; i++ { | |
s <- e | |
} | |
} | |
// release n resources | |
func (s semaphore) V(n int) { | |
for i := 0; i < n; i++ { | |
<-s | |
} | |
} | |
type store map[string]semaphore | |
func (s store) P(tag string, n int) chan empty { | |
log.Printf("Trying to lock") | |
if _, ok := s[tag]; !ok { | |
log.Printf("Created new tag %s", tag) | |
s[tag] = make(semaphore, 1) | |
} | |
ch := make(chan empty, 1) | |
log.Printf("TRYING TO LOCK %s", tag) | |
s[tag].P(n) | |
ch <- empty{} | |
log.Printf("LOCKED %s", tag) | |
return ch | |
} | |
func (s store) V(tag string, n int) { | |
if _, ok := s[tag]; !ok { | |
s[tag] = make(semaphore, 1) | |
} | |
s[tag].V(n) | |
} | |
var semaphoreStore store = make(store) | |
func handler(w http.ResponseWriter, r *http.Request) { | |
action := r.URL.Query().Get("action") | |
tag := r.URL.Query().Get("tag") | |
log.Printf("Found tag %s and action %s", tag, action) | |
timeout := time.NewTimer(10 * time.Second) | |
switch action { | |
case "lock": | |
select { | |
case <-semaphoreStore.P(tag, 1): | |
log.Printf("GOT A LOCK") | |
w.WriteHeader(200) | |
return | |
case <-timeout.C: | |
log.Printf("TIMED OUT WAITING FOR LOCK") | |
w.WriteHeader(403) | |
return | |
} | |
case "unlock": | |
semaphoreStore.V(tag, 1) | |
log.Printf("UNLOCKED") | |
w.WriteHeader(200) | |
return | |
} | |
log.Printf("No case was found") | |
w.WriteHeader(500) | |
return | |
} | |
func main() { | |
log.Printf("Starting semaphore server") | |
http.HandleFunc("/", handler) | |
log.Fatal(http.ListenAndServe(":8080", nil)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// :( |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment