code to stream stdout to the browser

This commit is contained in:
Brad Rydzewski 2014-07-11 19:10:18 -07:00
parent 6375eaa552
commit d000ca2918
9 changed files with 37 additions and 52 deletions

View file

@ -31,6 +31,8 @@
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.6.0/moment.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.6.0/moment.min.js"></script>
<!-- main javascript application --> <!-- main javascript application -->
<script src="/scripts/line_formatter.js"></script>
<script src="/scripts/commit_updates.js"></script>
<script src="/scripts/app.js"></script> <script src="/scripts/app.js"></script>
<script src="/scripts/controllers/conf.js"></script> <script src="/scripts/controllers/conf.js"></script>
<script src="/scripts/controllers/home.js"></script> <script src="/scripts/controllers/home.js"></script>

View file

@ -213,11 +213,11 @@ app.controller("CommitController", function($scope, $http, $routeParams, stdout,
var name = $routeParams.name; var name = $routeParams.name;
var branch = $routeParams.branch; var branch = $routeParams.branch;
var commit = $routeParams.commit; var commit = $routeParams.commit;
$scope.console='';
feed.subscribe(function(item) { feed.subscribe(function(item) {
// if the if (item.commit.sha == commit &&
if (item.commit.sha == commit item.commit.branch == branch) {
&& item.commit.branch == branch) {
$scope.commit = item.commit; $scope.commit = item.commit;
$scope.$apply(); $scope.$apply();
} else { } else {
@ -247,15 +247,20 @@ app.controller("CommitController", function($scope, $http, $routeParams, stdout,
if (data.status!='Started' && data.status!='Pending') { if (data.status!='Started' && data.status!='Pending') {
$http({method: 'GET', url: '/v1/repos/'+remote+'/'+owner+"/"+name+"/branches/"+branch+"/commits/"+commit+"/console"}). $http({method: 'GET', url: '/v1/repos/'+remote+'/'+owner+"/"+name+"/branches/"+branch+"/commits/"+commit+"/console"}).
success(function(data, status, headers, config) { success(function(data, status, headers, config) {
$scope.console = data; var lineFormatter = new Drone.LineFormatter();
var el = document.querySelector('#output');
angular.element(el).append(lineFormatter.format(data));
}). }).
error(function(data, status, headers, config) { error(function(data, status, headers, config) {
console.log(data); console.log(data);
}); });
return;
} }
var lineFormatter = new Drone.LineFormatter();
var el = document.querySelector('#output');
stdout.subscribe(data.id, function(out){ stdout.subscribe(data.id, function(out){
console.log(out); angular.element(el).append(lineFormatter.format(out));
}); });
}). }).
error(function(data, status, headers, config) { error(function(data, status, headers, config) {

View file

@ -3,49 +3,29 @@
if(typeof(Drone) === 'undefined') { Drone = {}; } if(typeof(Drone) === 'undefined') { Drone = {}; }
(function () { (function () {
Drone.CommitUpdates = function(socket) { Drone.Console = function() {
if(typeof(socket) === "string") {
var url = [(window.location.protocol == 'https:' ? 'wss' : 'ws'),
'://',
window.location.host,
socket].join('')
this.socket = new WebSocket(url);
} else {
this.socket = socket;
}
this.lineFormatter = new Drone.LineFormatter(); this.lineFormatter = new Drone.LineFormatter();
this.attach();
} }
Drone.CommitUpdates.prototype = { Drone.Console.prototype = {
lineBuffer: "", lineBuffer: "",
autoFollow: false, autoFollow: false,
startOutput: function(el) { start: function(el) {
if(typeof(el) === 'string') { if(typeof(el) === 'string') {
this.el = document.getElementById(el); this.el = document.getElementById(el);
} else { } else {
this.el = el; this.el = el;
} }
if(!this.reqId) { this.update();
this.updateScreen();
}
}, },
stopOutput: function() { stop: function() {
this.stoppingRefresh = true; this.stoppingRefresh = true;
}, },
attach: function() { update: function() {
this.socket.onopen = this.onOpen;
this.socket.onerror = this.onError;
this.socket.onmessage = this.onMessage.bind(this);
this.socket.onclose = this.onClose;
},
updateScreen: function() {
if(this.lineBuffer.length > 0) { if(this.lineBuffer.length > 0) {
this.el.innerHTML += this.lineBuffer; this.el.innerHTML += this.lineBuffer;
this.lineBuffer = ''; this.lineBuffer = '';
@ -62,21 +42,8 @@ if(typeof(Drone) === 'undefined') { Drone = {}; }
} }
}, },
onOpen: function() { write: function(e) {
console.log('output websocket open');
},
onError: function(e) {
console.log('websocket error: ' + e);
},
onMessage: function(e) {
this.lineBuffer += this.lineFormatter.format(e.data); this.lineBuffer += this.lineFormatter.format(e.data);
},
onClose: function(e) {
console.log('output websocket closed: ' + JSON.stringify(e));
window.location.reload();
} }
}; };

View file

@ -24,6 +24,7 @@ angular.module('app').service('stdout', ['$window', function($window) {
this.unsubscribe = function() { this.unsubscribe = function() {
callback = undefined; callback = undefined;
if (websocket != undefined) { if (websocket != undefined) {
console.log('unsubscribing websocket at '+websocket.url);
websocket.close(); websocket.close();
} }
}; };

View file

@ -29,6 +29,6 @@
<a href="#">{{ commit.sha | shortHash}}</a> <a href="#">{{ commit.sha | shortHash}}</a>
</nav> </nav>
<pre>{{ console }}</pre> <pre id="output"></pre>
</div> </div>
</div> </div>

View file

@ -46,8 +46,6 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error {
return nil return nil
} }
//fmt.Printf("%#v", hook)
// fetch the repository from the database // fetch the repository from the database
repo, err := h.repos.FindName(remote.GetHost(), hook.Owner, hook.Repo) repo, err := h.repos.FindName(remote.GetHost(), hook.Owner, hook.Repo)
if err != nil { if err != nil {

View file

@ -1,6 +1,7 @@
package handler package handler
import ( import (
"log"
"net/http" "net/http"
"strconv" "strconv"
"time" "time"
@ -157,16 +158,19 @@ func (h *WsHandler) WsConsole(w http.ResponseWriter, r *http.Request) error {
ws.SetWriteDeadline(time.Now().Add(writeWait)) ws.SetWriteDeadline(time.Now().Add(writeWait))
err := ws.WriteMessage(websocket.TextMessage, data) err := ws.WriteMessage(websocket.TextMessage, data)
if err != nil { if err != nil {
log.Println("websocket for commit %d closed. Err: %s", commitID, err)
ws.Close() ws.Close()
return return
} }
case <-sub.CloseNotify(): case <-sub.CloseNotify():
log.Println("websocket for commit %d closed by client", commitID)
ws.Close() ws.Close()
return return
case <-ticker.C: case <-ticker.C:
ws.SetWriteDeadline(time.Now().Add(writeWait)) ws.SetWriteDeadline(time.Now().Add(writeWait))
err := ws.WriteMessage(websocket.PingMessage, []byte{}) err := ws.WriteMessage(websocket.PingMessage, []byte{})
if err != nil { if err != nil {
log.Println("websocket for commit %d closed. Err: %s", commitID, err)
ws.Close() ws.Close()
return return
} }

View file

@ -1,6 +1,7 @@
package pubsub package pubsub
import ( import (
"log"
"time" "time"
) )
@ -47,7 +48,9 @@ func (c *Channel) start() {
// if somehow we encounter a nil pointer or some // if somehow we encounter a nil pointer or some
// other unexpected behavior. // other unexpected behavior.
defer func() { defer func() {
recover() if r := recover(); r != nil {
log.Println("recoved from panic", r)
}
}() }()
// timeout the channel after N duration // timeout the channel after N duration
@ -63,6 +66,7 @@ func (c *Channel) start() {
case sub := <-c.unsubscribe: case sub := <-c.unsubscribe:
delete(c.subscriptions, sub) delete(c.subscriptions, sub)
close(sub.send) close(sub.send)
log.Println("usubscribed to subscription")
case sub := <-c.subscribe: case sub := <-c.subscribe:
c.subscriptions[sub] = true c.subscriptions[sub] = true
@ -89,15 +93,18 @@ func (c *Channel) start() {
select { select {
case sub.send <- msg: case sub.send <- msg:
// do nothing // do nothing
default: //default:
sub.Close() // log.Println("subscription closed in inner select")
// sub.Close()
} }
} }
case <-timeout: case <-timeout:
log.Println("subscription's timedout channel received message")
c.Close() c.Close()
case <-c.closed: case <-c.closed:
log.Println("subscription's close channel received message")
c.stop() c.stop()
return return
} }
@ -111,6 +118,7 @@ func replay(s *Subscription, history []interface{}) {
} }
func (c *Channel) stop() { func (c *Channel) stop() {
log.Println("subscription stopped")
for sub := range c.subscriptions { for sub := range c.subscriptions {
sub.Close() sub.Close()
} }

View file

@ -21,6 +21,6 @@ var DefaultOpts = &Opts{
} }
var ConsoleOpts = &Opts{ var ConsoleOpts = &Opts{
Timeout: time.Minute * 60, Timeout: time.Minute * 120,
Record: true, Record: true,
} }