goat 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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