drop the SSE, use client side fetch every 5s for thread updates
This commit is contained in:
		
							
								
								
									
										43
									
								
								apps/api.lua
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								apps/api.lua
									
									
									
									
									
								
							@@ -1,8 +1,6 @@
 | 
			
		||||
local app = require("lapis").Application()
 | 
			
		||||
local json_params = require("lapis.application").json_params
 | 
			
		||||
 | 
			
		||||
local sse = require("lib.sse")
 | 
			
		||||
 | 
			
		||||
local db = require("lapis.db")
 | 
			
		||||
 | 
			
		||||
local html_escape = require("lapis.html").escape
 | 
			
		||||
@@ -10,33 +8,26 @@ local babycode = require("lib.babycode")
 | 
			
		||||
 | 
			
		||||
local util = require("util")
 | 
			
		||||
 | 
			
		||||
app:get("sse_thread_updates", "/thread-updates/:thread_id", function(self)
 | 
			
		||||
  do
 | 
			
		||||
    local thread = db.query("SELECT threads.id FROM threads WHERE threads.id = ?", self.params.thread_id)
 | 
			
		||||
    if #thread == 0 then
 | 
			
		||||
      return {status = 404, skip_render = true}
 | 
			
		||||
    end
 | 
			
		||||
app:post("api_get_thread_updates", "/thread-updates/:thread_id", json_params(function(self)
 | 
			
		||||
  local thread = db.query("SELECT threads.id FROM threads WHERE threads.id = ?", self.params.thread_id)
 | 
			
		||||
  if #thread == 0 then
 | 
			
		||||
    return {json = {error = "no such thread"}, status = 404}
 | 
			
		||||
  end
 | 
			
		||||
  local target_time = self.params.since
 | 
			
		||||
  if not target_time then
 | 
			
		||||
    return {json = {error = "missing parameter 'since'"}, status = 400}
 | 
			
		||||
  end
 | 
			
		||||
  if not tonumber(target_time) then
 | 
			
		||||
    return {json = {error = "parameter 'since' is not a number"}, status = 400}
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  local now = os.time()
 | 
			
		||||
  local stream = sse:new()
 | 
			
		||||
  
 | 
			
		||||
  local thread_id = self.params.thread_id
 | 
			
		||||
  local new_posts_query = "SELECT id FROM posts WHERE thread_id = ? AND posts.created_at > ? ORDER BY posts.created_at ASC LIMIT 1"
 | 
			
		||||
  
 | 
			
		||||
  while stream.active do
 | 
			
		||||
    stream:dispatch()
 | 
			
		||||
    local new_post = db.query(new_posts_query, thread_id, now)
 | 
			
		||||
    if #new_post > 0 then
 | 
			
		||||
      local url = util.get_post_url(self, new_post[1].id)
 | 
			
		||||
      stream:enqueue(url, "new_post_url")
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    ngx.sleep(5)
 | 
			
		||||
  local new_post = db.query(new_posts_query, self.params.thread_id, target_time)
 | 
			
		||||
  if #new_post == 0 then
 | 
			
		||||
    return {json = {status = "none"}, status = 200}
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  return {skip_render = true}
 | 
			
		||||
end)
 | 
			
		||||
  local url = util.get_post_url(self, new_post[1].id)
 | 
			
		||||
  return {json = {status = "new_post", url = url}}
 | 
			
		||||
end))
 | 
			
		||||
 | 
			
		||||
app:post("babycode_preview", "/babycode-preview", json_params(function(self)
 | 
			
		||||
  local user = util.get_logged_in_user(self)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								js/thread.js
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								js/thread.js
									
									
									
									
									
								
							@@ -37,8 +37,8 @@
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  let newPostSubscription = null;
 | 
			
		||||
  
 | 
			
		||||
  const threadEndpoint = document.getElementById("thread-subscribe-endpoint").value;
 | 
			
		||||
  let now = Math.floor(new Date() / 1000);
 | 
			
		||||
  function hideNotification() {
 | 
			
		||||
    const notification = document.getElementById('new-post-notification');
 | 
			
		||||
    notification.classList.add('hidden');
 | 
			
		||||
@@ -50,35 +50,31 @@
 | 
			
		||||
    notification.classList.remove("hidden");
 | 
			
		||||
    
 | 
			
		||||
    document.getElementById("dismiss-new-post-button").onclick = () => {
 | 
			
		||||
      now = Math.floor(new Date() / 1000);
 | 
			
		||||
      hideNotification();
 | 
			
		||||
      reconnectSSE();
 | 
			
		||||
      tryFetchUpdate();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    document.getElementById("go-to-new-post-button").href = url;
 | 
			
		||||
    
 | 
			
		||||
    document.getElementById("unsub-new-post-button").onclick = () => {
 | 
			
		||||
      hideNotification()
 | 
			
		||||
      hideNotification();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  function reconnectSSE() {
 | 
			
		||||
    if (newPostSubscription) newPostSubscription.close();
 | 
			
		||||
    
 | 
			
		||||
    const threadEndpoint = document.getElementById("thread-subscribe-endpoint").value;
 | 
			
		||||
    newPostSubscription = new EventSource(threadEndpoint);
 | 
			
		||||
    newPostSubscription.onerror = (e) => {
 | 
			
		||||
      console.error(e);
 | 
			
		||||
    };
 | 
			
		||||
    newPostSubscription.addEventListener("new_post_url", (e) => {
 | 
			
		||||
      showNewPostNotification(e.data);
 | 
			
		||||
      newPostSubscription.close();
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
  function tryFetchUpdate() {
 | 
			
		||||
    if (!threadEndpoint) return;
 | 
			
		||||
    const body = JSON.stringify({since: now});
 | 
			
		||||
    fetch(threadEndpoint, {method: "POST", headers: {"Content-Type": "application/json"}, body: body})
 | 
			
		||||
      .then(res => res.json())
 | 
			
		||||
      .then(json => {
 | 
			
		||||
        if (json.status === "none") {
 | 
			
		||||
          setTimeout(tryFetchUpdate, 5000);
 | 
			
		||||
        } else if (json.status === "new_post") {
 | 
			
		||||
          showNewPostNotification(json.url);
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .catch(error => console.log(error))
 | 
			
		||||
  }
 | 
			
		||||
  window.addEventListener('beforeunload', () => {
 | 
			
		||||
    if(newPostSubscription)
 | 
			
		||||
    {
 | 
			
		||||
      newPostSubscription.close();
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  reconnectSSE();
 | 
			
		||||
  tryFetchUpdate();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -64,6 +64,6 @@
 | 
			
		||||
    </span>
 | 
			
		||||
  </div>
 | 
			
		||||
</dialog>
 | 
			
		||||
<input type="hidden" id="thread-subscribe-endpoint" value="<%= url_for("sse_thread_updates", {thread_id = thread.id}) %>">
 | 
			
		||||
<input type="hidden" id="thread-subscribe-endpoint" value="<%= url_for("api_get_thread_updates", {thread_id = thread.id}, {since = os.time()}) %>">
 | 
			
		||||
<% render("views.threads.new-post-notification") %>
 | 
			
		||||
<script src="/static/js/thread.js"></script>
 | 
			
		||||
<script src="/static/js/thread.js?v=1"></script>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user