Ejemplo n.º 1
0
func (w *StreamWriter) Write(data []byte) (int, error) {
	var err = sse.Encode(w.writer, sse.Event{
		Id:    strconv.Itoa(w.count),
		Event: "message",
		Data:  string(data),
	})
	w.writer.Flush()
	w.count += len(data)
	return len(data), err
}
Ejemplo n.º 2
0
func (c *conn) Send(msg common.Message) error {
	buf := new(bytes.Buffer)
	err := sse.Encode(buf, sse.Event{
		Event: msg.Name(),
		Id:    msg.Id(),
		Data:  msg.Data(),
	})
	if err != nil {
		return err
	}
	return c.socket.WriteMessage(websocket.TextMessage, buf.Bytes())
}
Ejemplo n.º 3
0
func GetStream(c *gin.Context) {

	repo := session.Repo(c)
	buildn, _ := strconv.Atoi(c.Param("build"))
	jobn, _ := strconv.Atoi(c.Param("number"))

	c.Writer.Header().Set("Content-Type", "text/event-stream")

	build, err := store.GetBuildNumber(c, repo, buildn)
	if err != nil {
		log.Debugln("stream cannot get build number.", err)
		c.AbortWithError(404, err)
		return
	}
	job, err := store.GetJobNumber(c, build, jobn)
	if err != nil {
		log.Debugln("stream cannot get job number.", err)
		c.AbortWithError(404, err)
		return
	}

	rc, err := stream.Reader(c, stream.ToKey(job.ID))
	if err != nil {
		c.AbortWithError(404, err)
		return
	}

	go func() {
		<-c.Writer.CloseNotify()
		rc.Close()
	}()

	var line int
	var scanner = bufio.NewScanner(rc)
	for scanner.Scan() {
		line++
		var err = sse.Encode(c.Writer, sse.Event{
			Id:    strconv.Itoa(line),
			Event: "message",
			Data:  scanner.Text(),
		})
		if err != nil {
			break
		}
		c.Writer.Flush()
	}

	log.Debugf("Closed stream %s#%d", repo.FullName, build.Number)
}
Ejemplo n.º 4
0
// GetRepoEvents will upgrade the connection to a Websocket and will stream
// event updates to the browser.
func GetRepoEvents(c *gin.Context) {
	repo := session.Repo(c)
	c.Writer.Header().Set("Content-Type", "text/event-stream")

	eventc := make(chan *bus.Event, 1)
	bus.Subscribe(c, eventc)
	defer func() {
		bus.Unsubscribe(c, eventc)
		close(eventc)
		log.Infof("closed event stream")
	}()

	c.Stream(func(w io.Writer) bool {
		select {
		case event := <-eventc:
			if event == nil {
				log.Infof("nil event received")
				return false
			}

			// TODO(bradrydzewski) This is a super hacky workaround until we improve
			// the actual bus. Having a per-call database event is just plain stupid.
			if event.Repo.FullName == repo.FullName {

				var payload = struct {
					model.Build
					Jobs []*model.Job `json:"jobs"`
				}{}
				payload.Build = event.Build
				payload.Jobs, _ = store.GetJobList(c, &event.Build)
				data, _ := json.Marshal(&payload)

				sse.Encode(w, sse.Event{
					Event: "message",
					Data:  string(data),
				})
			}
		case <-c.Writer.CloseNotify():
			return false
		}
		return true
	})
}
Ejemplo n.º 5
-1
// GetRepoEvents will upgrade the connection to a Websocket and will stream
// event updates to the browser.
func GetRepoEvents(c *gin.Context) {
	engine_ := context.Engine(c)
	repo := session.Repo(c)
	c.Writer.Header().Set("Content-Type", "text/event-stream")

	eventc := make(chan *engine.Event, 1)
	engine_.Subscribe(eventc)
	defer func() {
		engine_.Unsubscribe(eventc)
		close(eventc)
		log.Infof("closed event stream")
	}()

	c.Stream(func(w io.Writer) bool {
		select {
		case event := <-eventc:
			if event == nil {
				log.Infof("nil event received")
				return false
			}
			if event.Name == repo.FullName {
				log.Debugf("received message %s", event.Name)
				sse.Encode(w, sse.Event{
					Event: "message",
					Data:  string(event.Msg),
				})
			}
		case <-c.Writer.CloseNotify():
			return false
		}
		return true
	})
}