goat 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/goat.rb +10 -4
- data/lib/goat/goat.js +36 -24
- metadata +3 -3
data/lib/goat.rb
CHANGED
@@ -204,9 +204,10 @@ module Goat
|
|
204
204
|
class ChannelPusher
|
205
205
|
include EM::Deferrable
|
206
206
|
|
207
|
-
def initialize(channel)
|
207
|
+
def initialize(channel, jsonp)
|
208
208
|
@channel = channel
|
209
209
|
@finished = false
|
210
|
+
@jsonp = jsonp
|
210
211
|
@messages = []
|
211
212
|
|
212
213
|
self.errback do
|
@@ -245,7 +246,7 @@ module Goat
|
|
245
246
|
|
246
247
|
def send_and_finish
|
247
248
|
return if @finished # may be called several times
|
248
|
-
@body_callback.call({'messages' => messages_without_duplicates}.to_json)
|
249
|
+
@body_callback.call("#{@jsonp}(#{{'messages' => messages_without_duplicates}.to_json})")
|
249
250
|
succeed
|
250
251
|
end
|
251
252
|
|
@@ -587,16 +588,21 @@ module Goat
|
|
587
588
|
|
588
589
|
def handle_channel(req)
|
589
590
|
id = req['_id']
|
591
|
+
jsonp = req['jsonp']
|
590
592
|
pg = active_pages[id]
|
591
593
|
|
592
594
|
active_page_gc # we do GC here since a slight delay in opening channel is better than in loading page
|
593
595
|
|
596
|
+
if !jsonp
|
597
|
+
respond_failed
|
598
|
+
end
|
599
|
+
|
594
600
|
if pg
|
595
601
|
pg.mark_alive!
|
596
|
-
body = ChannelPusher.new(pg.channel)
|
602
|
+
body = ChannelPusher.new(pg.channel, jsonp)
|
597
603
|
|
598
604
|
EM.next_tick do
|
599
|
-
req.env['async.callback'].call([200, {}, body])
|
605
|
+
req.env['async.callback'].call([200, {'Content-Type' => 'application/javascript'}, body])
|
600
606
|
end
|
601
607
|
|
602
608
|
body.callback { pg.mark_dead! }
|
data/lib/goat/goat.js
CHANGED
@@ -70,14 +70,12 @@ $.extend(Goat, {
|
|
70
70
|
},
|
71
71
|
|
72
72
|
channelDataReceived: function(data) {
|
73
|
-
if(data
|
73
|
+
if(!data) {
|
74
|
+
console.log("Null data received in channelDataReceived")
|
74
75
|
this.reopenChannel();
|
75
76
|
return;
|
76
77
|
}
|
77
|
-
|
78
|
-
// console.warn("channel data: " + data);
|
79
|
-
data = $.evalJSON(data);
|
80
|
-
|
78
|
+
|
81
79
|
this.channelOpenFails = 0;
|
82
80
|
|
83
81
|
if(this.messageReceivedDelegate)
|
@@ -85,7 +83,6 @@ $.extend(Goat, {
|
|
85
83
|
|
86
84
|
if(data['messages']) {
|
87
85
|
$(data['messages']).each(this.closure(function(i, m) { this.messageReceived(m) }));
|
88
|
-
this.openChannel();
|
89
86
|
} else {
|
90
87
|
console.error("Bad channel data: " + data)
|
91
88
|
}
|
@@ -94,35 +91,50 @@ $.extend(Goat, {
|
|
94
91
|
reopenChannel: function() {
|
95
92
|
console.log("reopenChannel()");
|
96
93
|
var fails = this.channelOpenFails;
|
97
|
-
setTimeout(function() { Goat.openChannel(); }, (
|
94
|
+
setTimeout(function() { Goat.openChannel(); }, Math.min(30000, Math.pow(1.5, fails)));
|
98
95
|
this.channelOpenFails++;
|
99
96
|
},
|
100
97
|
|
101
98
|
openChannel: function() {
|
102
99
|
console.log("opening channel");
|
103
|
-
|
100
|
+
|
104
101
|
if(this.activeChannel) {
|
105
102
|
console.error("can't open channel: channel already open");
|
106
103
|
return;
|
107
104
|
}
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
this.channelDataReceived(data);
|
118
|
-
}),
|
119
|
-
error: this.closure(function(req, status, err) {
|
105
|
+
|
106
|
+
var head = document.getElementsByTagName('head')[0];
|
107
|
+
var scriptTag = document.createElement('script');
|
108
|
+
var jsonp = 'jsonp' + Math.random().toString(16).split(".").pop();
|
109
|
+
|
110
|
+
var cleanup = closure(this, function() {
|
111
|
+
window[jsonp] = null;
|
112
|
+
if(scriptTag && scriptTag.parentNode) {
|
113
|
+
scriptTag.parentNode.removeChild(scriptTag);
|
120
114
|
this.activeChannel = null;
|
121
|
-
|
122
|
-
console.error({req: req, status: status, err: err});
|
123
|
-
this.reopenChannel();
|
124
|
-
})
|
115
|
+
}
|
125
116
|
});
|
117
|
+
|
118
|
+
window[jsonp] = closure(this, function(data) { cleanup(); this.channelDataReceived(data); })
|
119
|
+
|
120
|
+
function injectScriptTag(tag) {
|
121
|
+
|
122
|
+
var logError = closure(this, function() {
|
123
|
+
console.error("Goat: error loading " + src);
|
124
|
+
});
|
125
|
+
|
126
|
+
var src = '/channel?_id=' + Goat.page_id + '&jsonp=' + jsonp;
|
127
|
+
|
128
|
+
scriptTag.addEventListener('load', function() { cleanup(); Goat.reopenChannel(); }, false);
|
129
|
+
scriptTag.addEventListener('error', function() { cleanup(); logError(); Goat.reopenChannel(); }, false);
|
130
|
+
scriptTag.src = src;
|
131
|
+
|
132
|
+
Goat.activeChannel = scriptTag;
|
133
|
+
|
134
|
+
head.insertBefore(scriptTag, head.children[0]);
|
135
|
+
}
|
136
|
+
|
137
|
+
injectScriptTag();
|
126
138
|
},
|
127
139
|
|
128
140
|
submitForm: function(id) {
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: goat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 4
|
10
|
+
version: 0.2.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Patrick Collison
|