{"action":"created","issue":{"url":"https://api.github.com/repos/decebals/pippo/issues/81","labels_url":"https://api.github.com/repos/decebals/pippo/issues/81/labels{/name}","comments_url":"https://api.github.com/repos/decebals/pippo/issues/81/comments","events_url":"https://api.github.com/repos/decebals/pippo/issues/81/events","html_url":"https://github.com/decebals/pippo/issues/81","id":55511131,"number":81,"title":"Cleaning up a request-response cycle regardless of errors","user":{"login":"gitblit","id":868217,"avatar_url":"https://avatars.githubusercontent.com/u/868217?v=3","gravatar_id":"","url":"https://api.github.com/users/gitblit","html_url":"https://github.com/gitblit","followers_url":"https://api.github.com/users/gitblit/followers","following_url":"https://api.github.com/users/gitblit/following{/other_user}","gists_url":"https://api.github.com/users/gitblit/gists{/gist_id}","starred_url":"https://api.github.com/users/gitblit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gitblit/subscriptions","organizations_url":"https://api.github.com/users/gitblit/orgs","repos_url":"https://api.github.com/users/gitblit/repos","events_url":"https://api.github.com/users/gitblit/events{/privacy}","received_events_url":"https://api.github.com/users/gitblit/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-01-26T17:25:57Z","updated_at":"2015-01-28T18:55:03Z","closed_at":null,"body":"Consider this scenario where we are getting a Db instance to be shared throughout a request-response cycle:\r\n\r\n```java\r\n// Preparation route for \r\nALL(\"/.*\", (request, response, chain) -> {\r\n    response.bind(\"db\", getDb());\r\n}); \r\n\r\nPOST(\"/{id}\", (request, response, chain) -> {\r\n    Db db = (Db) response.getLocals().get(\"db\");\r\n    // this throws an runtime exception somewhere deep inside\r\n    db.insert(something);\r\n});\r\n\r\n// Cleanup route\r\nALL(\"/.*\", (request, response, chain) -> {\r\n    Db db = (Db) response.getLocals().remove(\"db\");\r\n    db.release();\r\n}); \r\n```\r\n\r\nIf an exception is thrown in `POST` then the cleanup route is never executed and we are now leaking Db connections.  Instead of trapping Db exceptions in every handler, it would be nice to be able to specify cleanup routes/routines that are guaranteed to execute at the end of the Request-Response cycle **despite** exceptions within the chain.  These mechanisms should be fail-safe themselves and should not have a `chain` parameter.\r\n\r\n```java\r\nvoid cleanup(Request request, Response response);\r\n```\r\n\r\nThe `RouteHandlerChain` or `PippoFilter` should execute these cleanup routines within independent `try {} catch {}` blocks.\r\n\r\n```java\r\nfor (CleanupHandler handler : cleanupHandlers) {\r\n    try {\r\n        handler.cleanup(request, response);\r\n    } catch (Exception e) {\r\n        log.error(\"Whoops\", e);\r\n    }\r\n}\r\n```\r\n\r\nPerhaps these could be registered as:\r\n\r\n```java\r\n// Cleanup route\r\nCLEANUP(\"/.*\", (request, response) -> {\r\n    Db db = (Db) response.getLocals().remove(\"db\");\r\n    db.release();\r\n}); \r\n``````"},"comment":{"url":"https://api.github.com/repos/decebals/pippo/issues/comments/71892779","html_url":"https://github.com/decebals/pippo/issues/81#issuecomment-71892779","issue_url":"https://api.github.com/repos/decebals/pippo/issues/81","id":71892779,"user":{"login":"decebals","id":1248311,"avatar_url":"https://avatars.githubusercontent.com/u/1248311?v=3","gravatar_id":"","url":"https://api.github.com/users/decebals","html_url":"https://github.com/decebals","followers_url":"https://api.github.com/users/decebals/followers","following_url":"https://api.github.com/users/decebals/following{/other_user}","gists_url":"https://api.github.com/users/decebals/gists{/gist_id}","starred_url":"https://api.github.com/users/decebals/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/decebals/subscriptions","organizations_url":"https://api.github.com/users/decebals/orgs","repos_url":"https://api.github.com/users/decebals/repos","events_url":"https://api.github.com/users/decebals/events{/privacy}","received_events_url":"https://api.github.com/users/decebals/received_events","type":"User","site_admin":false},"created_at":"2015-01-28T18:55:03Z","updated_at":"2015-01-28T18:55:03Z","body":"It's important for adoption to have a steep learning curve. For this reason I wish to not introduce new concepts if not necessarily need.\r\n> I guess the real question should be: is cleanup/finally a filter or is it a listener?\r\n\r\nI prefer a filter.\r\nI propose an idea introduced by James (gitblit) in https://github.com/decebals/pippo/issues/66.\r\nThe idea consists in:\r\n- returns a Route in `Application.ALL` (in don't know if it's ok to make this modification for other methods - GET for example)\r\n- add a `cleanup/finally` method to Route\r\n\r\n```java\r\nALL(\"/.*\", (request, response, chain) -> {\r\n    >> here close database connection\r\n}).cleanupOrFinally();\r\n```\r\n\r\nMake sense?"}}