goat 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/goat.rb +10 -4
  2. data/lib/goat/goat.js +36 -24
  3. metadata +3 -3
@@ -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! }
@@ -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(); }, (fails > 20) ? 20000 : (fails * 500));
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
- this.activeChannel = $.ajax({
110
- url: '/channel',
111
- async: true,
112
- data: {_id: Goat.page_id},
113
- cache: false,
114
- timeout: 1000000,
115
- success: this.closure(function(data) {
116
- this.activeChannel = null;
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
- console.error("ajax channel error");
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: 17
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 3
10
- version: 0.2.3
9
+ - 4
10
+ version: 0.2.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Patrick Collison