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 = user

JavaScript (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))
end

C# (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