Now OneFeed supports commenting.
Since post pages are cached for quick access, a tiny modification is needed to accept POST
request initiated from the cached pages.
authenticity_token
s in comment creation form of cached pages are usually out-of-date.
<form action="/posts/post-x-link/comments" method="post">
<input type="hidden" name="authenticity_token" value="zzcjgpp55...+yxjDy4LmydrMVqsAfQ/+igqKDcIAg==">
Rails uses these authenticity_token
s to prevent CSRF attack.
Skip this protection for comment :create
method.
class CommentsController < ApplicationController
protect_from_forgery except: :create
Rate Limit
And a rate limit is set for POST
request of comment creation.
It’s simply implemented on top of Redis.
def exceed_limit?
key = request.remote_ip
if EXISTS key
return true # the ip has been submitted a comment lately
else
INCR key
EXPIRE key, CREATION_RATE_LIMIT
return false
end
end
A more complex API rate limit can be implemented using “leaky bucket” algorithm.
This allows for infrequent bursts of calls, and allows your app to continue to make an unlimited amount of calls over time.
Shopify implements its API rate limit in that way.
The bucket size is 40 calls (which cannot be exceeded at any given time), with a “leak rate” of 2 calls per second that continually empties the bucket. If your app averages 2 calls per second, it will never trip a 429 error (“bucket overflow”).
Flash
When POST
request is rejected due to rate limitation, a flash message is shown to alert the user, which is meant to be short-lived.
At first implementation, the flash message was statically embedded into posts/show.html.erb
.
<div class="flash-msgs screen-center">
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, class: [name, "flash-msg", "fade-out", "bg-danger"] %>
<% end %>
</div>
Unfortunately, it means that the flash message was sticked in the page cache (until another operation invalidates that cache).
To fix this bug, POST
request is implemented in AJAX way, so that flash messages can be embedded dynamically.
Every layer introduced into system adds more complexity into system at last🤔.