main
parent
ce1c1e0205
commit
74830411d0
|
|
@ -7,5 +7,48 @@
|
||||||
<h1>Hello World</h1>
|
<h1>Hello World</h1>
|
||||||
</body>
|
</body>
|
||||||
<footer>
|
<footer>
|
||||||
|
<script>
|
||||||
|
let g_questions = [];
|
||||||
|
let g_live_question = {};
|
||||||
|
|
||||||
|
function pollState() {
|
||||||
|
http("GET", "/api/v1/questions", (body) => {
|
||||||
|
g_questions = JSON.parse(body);
|
||||||
|
console.log("polled state:", body);
|
||||||
|
pollLiveAnswer();
|
||||||
|
pollLiveQuestion();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function pollLiveQuestion() {
|
||||||
|
let live_questions = g_questions.filter((q) => q.Live);
|
||||||
|
if (live_questions) {
|
||||||
|
g_live_question = live_questions[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pollLiveAnswer() {
|
||||||
|
if (!g_live_question || !g_live_question.Closed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function http(method, remote, callback, body) {
|
||||||
|
var xmlhttp = new XMLHttpRequest();
|
||||||
|
xmlhttp.onreadystatechange = function() {
|
||||||
|
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
|
||||||
|
callback(xmlhttp.responseText, xmlhttp.status)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xmlhttp.open(method, remote, true);
|
||||||
|
if(typeof body == "undefined") {
|
||||||
|
body = null
|
||||||
|
}
|
||||||
|
xmlhttp.send(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
pollState();
|
||||||
|
setInterval(() => { pollState(); }, 1000);
|
||||||
|
</script>
|
||||||
</footer>
|
</footer>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ type Handler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB interface {
|
type DB interface {
|
||||||
GetQuestions() ([]string, error)
|
GetQuestions() ([]Question, error)
|
||||||
GetQuestion(string) (Question, error)
|
GetQuestion(string) (Question, error)
|
||||||
InsertAnswer(string, string, Answer) error
|
InsertAnswer(string, string, Answer) error
|
||||||
GetAnswers(string) ([]Answer, error)
|
GetAnswers(string) ([]Answer, error)
|
||||||
|
|
@ -42,6 +42,9 @@ type DB interface {
|
||||||
type fsDB string
|
type fsDB string
|
||||||
|
|
||||||
type Question struct {
|
type Question struct {
|
||||||
|
ID string
|
||||||
|
Live bool
|
||||||
|
Closed bool
|
||||||
Text string
|
Text string
|
||||||
Options []string
|
Options []string
|
||||||
}
|
}
|
||||||
|
|
@ -79,6 +82,7 @@ func newConfig() (Config, error) {
|
||||||
fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
|
fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
|
||||||
fs.StringVar(&cfg.Addr, "addr", ":8080", "address to listen on")
|
fs.StringVar(&cfg.Addr, "addr", ":8080", "address to listen on")
|
||||||
fs.IntVar(&cfg.RPS, "rps", 100, "requests per second to serve")
|
fs.IntVar(&cfg.RPS, "rps", 100, "requests per second to serve")
|
||||||
|
fs.StringVar(&cfg.fsDB, "fs-db", "/tmp/live-audience.d", "api dir to serve")
|
||||||
|
|
||||||
err := fs.Parse(os.Args[1:])
|
err := fs.Parse(os.Args[1:])
|
||||||
return cfg, err
|
return cfg, err
|
||||||
|
|
@ -234,6 +238,7 @@ func (db fsDB) GetQuestion(qid string) (Question, error) {
|
||||||
if err := json.Unmarshal(b, &q); err != nil {
|
if err := json.Unmarshal(b, &q); err != nil {
|
||||||
return Question{}, err
|
return Question{}, err
|
||||||
}
|
}
|
||||||
|
q.ID = qid
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,15 +255,20 @@ func (db fsDB) InsertAnswer(qid, uid string, a Answer) error {
|
||||||
return os.WriteFile(p, b, os.ModePerm)
|
return os.WriteFile(p, b, os.ModePerm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db fsDB) GetQuestions() ([]string, error) {
|
func (db fsDB) GetQuestions() ([]Question, error) {
|
||||||
p := db.path("")
|
p := db.path("")
|
||||||
entries, err := os.ReadDir(p)
|
entries, err := os.ReadDir(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
results := []string{}
|
results := []Question{}
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
results = append(results, path.Base(entry.Name()))
|
qid := path.Base(entry.Name())
|
||||||
|
q, err := db.GetQuestion(qid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results = append(results, q)
|
||||||
}
|
}
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,10 @@ func TestRunHTTP(t *testing.T) {
|
||||||
if w.Code != http.StatusOK {
|
if w.Code != http.StatusOK {
|
||||||
t.Error(w.Code)
|
t.Error(w.Code)
|
||||||
}
|
}
|
||||||
var result []string
|
var result []Question
|
||||||
if err := json.Unmarshal(w.Body.Bytes(), &result); err != nil {
|
if err := json.Unmarshal(w.Body.Bytes(), &result); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
} else if fmt.Sprint(result) != fmt.Sprint([]string{"0"}) {
|
} else if fmt.Sprint(result) != fmt.Sprint([]Question{{ID: "0", Live: false, Closed: false, Text: "QUESTION TEXT", Options: []string{"X", "Y"}}}) {
|
||||||
t.Error(result)
|
t.Error(result)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -100,7 +100,7 @@ func TestRunHTTP(t *testing.T) {
|
||||||
var result Question
|
var result Question
|
||||||
if err := json.Unmarshal(w.Body.Bytes(), &result); err != nil {
|
if err := json.Unmarshal(w.Body.Bytes(), &result); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
} else if fmt.Sprint(result) != fmt.Sprint(Question{Text: "QUESTION TEXT", Options: []string{"X", "Y"}}) {
|
} else if fmt.Sprint(result) != fmt.Sprint(Question{ID: "0", Text: "QUESTION TEXT", Options: []string{"X", "Y"}}) {
|
||||||
t.Error(result)
|
t.Error(result)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue