Metastatic.Analysis.BusinessLogic.BlockingInPlug
(Metastatic v0.10.4)
View Source
Detects blocking operations in request handling middleware.
Universal pattern: synchronous I/O in HTTP request middleware/interceptors.
Examples
Python (Django middleware with sync DB):
class AuthMiddleware:
def process_request(self, request):
user = User.objects.get(id=request.user_id) # Blocking DB query in middleware
request.user = userJavaScript (Express middleware with sync file I/O):
app.use((req, res, next) => {
const config = fs.readFileSync('config.json'); # Blocking file read
req.config = JSON.parse(config);
next();
});Elixir (Plug with blocking HTTP):
def call(conn, _opts) do
{:ok, response} = HTTPoison.get(verification_url) # Blocking in plug pipeline
assign(conn, :verified, verified?(response))
endC# (ASP.NET middleware with sync DB):
public class AuthMiddleware {
public void OnActionExecuting(ActionExecutingContext context) {
var user = db.Users.Find(userId); # Blocking DB in middleware
context.HttpContext.Items["user"] = user;
}
}Go (HTTP middleware with blocking call):
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user := getUser(r.Header.Get("Authorization")) # Should use context for cancellation
next.ServeHTTP(w, r)
})
}Java (Spring interceptor with sync I/O):
public class AuthInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request) {
User user = userRepository.findById(userId).get(); # Blocking DB query
request.setAttribute("user", user);
}
}Ruby (Rack middleware with blocking Redis):
class CacheMiddleware
def call(env)
cached = Redis.current.get(cache_key) # Synchronous Redis call in middleware
@app.call(env)
end
end