{"_id":"572a42d754312934004c74ea","__v":15,"user":"5723ea8efda3c70e005b88e3","version":{"_id":"5723eaebeae5090e00ee61f1","__v":3,"project":"5723ead0fda3c70e005b88e5","createdAt":"2016-04-29T23:14:51.190Z","releaseDate":"2016-04-29T23:14:51.190Z","categories":["5723eaebeae5090e00ee61f2","5723f854110e570e00486c7a","572a28f6d10a200e00b1cb14"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"0.1.0","version":"0.1"},"category":{"_id":"572a28f6d10a200e00b1cb14","__v":0,"version":"5723eaebeae5090e00ee61f1","project":"5723ead0fda3c70e005b88e5","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-05-04T16:53:10.034Z","from_sync":false,"order":1,"slug":"concepts","title":"Concepts"},"project":"5723ead0fda3c70e005b88e5","updates":["57899ca5f55bf80e00d0c345"],"next":{"pages":[],"description":""},"createdAt":"2016-05-04T18:43:35.877Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":999,"body":"[block:callout]\n{\n  \"type\": \"danger\",\n  \"title\": \"Notice\",\n  \"body\": \"Resources are an experimental feature of Lever OS. Please [report bugs as GitHub issues](https://github.com/leveros/leveros/issues/new).\"\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"Key takeaways\",\n  \"body\": \"* Resources allow you to shard data across the instances of a service.\\n* Resource identifiers are just strings that Lever binds to specific instances.\\n* Traffic asking for a specific resource is consistently routed to the same instance.\"\n}\n[/block]\nLever **resources** are identifiers that stick to the instance that first served them. This allows you to shard data across the instances of a service. Best illustrated with an example.\n\nSuppose you have a service called `myService` and right now, it has 3 instances serving trafic. Invoking the service like so repeatedly\n\n```bash\n$ lever invoke /myService/someMethod\n```\n\n... will cause the requests to be sprinkled onto all 3 instances, with no guarantees of where it might land next.\n\nBut if we specify a resource as part of the invokation like so\n\n```bash\n$ lever invoke /myService/shinyResource/someMethod\n```\n\n... then we are guaranteed that each time the request will be handled by the same instance every time.\n\nThis allows you to cache relevant information about that resource in the instance's memory. The next time that resource is invoked you will be able to reuse the cached data.\n\nThe resource identifier can be any string. If Lever has never seen that identifier before it will bind it with an instance on the spot. Subsequent requests for that identifier will be routed to the same instance.\n\nAlthough service and method names may not contain `/`, resource identifiers may. This allows you to create your own URL structure for resources belonging to the same service.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/v8yvggdiRNOabLRPnoxM_sharding.png\",\n        \"sharding.png\",\n        \"1587\",\n        \"1234\",\n        \"#940d0d\",\n        \"\"\n      ],\n      \"caption\": \"A resource invokation is routed to a specific instance\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Important\",\n  \"body\": \"Routing resources to the same instance is only guaranteed as long as that instance remains up. Lever OS may at any time stop that particular instance, which will cause that resource to be allocated to a different instance. Your implementation should handle this situation gracefully.\"\n}\n[/block]\n# Handling resource invokations\n\nAlthough each resource is handled by one instance at a time, each instance may handle more than one resource. It is the responsibility of the implementation of the methods to make the distinction when handling the request. The request identifier is typically passed as the first parameter (before the rest of the args) to the handling function - but you should consult the API reference for the language you are working with.\n\nIt is always a good idea to validate and sanitize resource identifiers. This is because for many public-facing services a rogue client can choose any resource string it wants, potentially causing injection attacks if not properly sanitized.\n\nTo help with managing resources on each instance, you can implement the methods below.\n\n### :arrow-right: `NewResource(resourceName)` *optional*\n\n* `resourceName` is the resource identifier.\n* **Returns** `null`.\n\nThis Lever method is invoked by the Lever OS subsystem when a resource is linked to the instance handling this call. The `NewResource` invokation is guaranteed to be called before any invokation belonging to that resource is called.\n\n### :arrow-right: `CloseResource(resourceName)` *optional*\n\n* `resourceName` is the resource identifier.\n* **Returns** `null`.\n\nThis Lever method is invoked by the Lever OS subsystem when a resource is unlinked from the instance handling this call. The `CloseResource` invokation is guaranteed to be called after all invokations belonging to that resource are called.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Important\",\n  \"body\": \"There is no guarantee that `CloseResource` is called every time. It is possible that the instance crashes or that Lever OS closes the instance before it has the opportunity to handle `CloseResource` calls.\"\n}\n[/block]","excerpt":"This page introduces you to the concept of Lever resources","slug":"resources","type":"basic","title":"Resources"}

Resources

This page introduces you to the concept of Lever resources

[block:callout] { "type": "danger", "title": "Notice", "body": "Resources are an experimental feature of Lever OS. Please [report bugs as GitHub issues](https://github.com/leveros/leveros/issues/new)." } [/block] [block:callout] { "type": "success", "title": "Key takeaways", "body": "* Resources allow you to shard data across the instances of a service.\n* Resource identifiers are just strings that Lever binds to specific instances.\n* Traffic asking for a specific resource is consistently routed to the same instance." } [/block] Lever **resources** are identifiers that stick to the instance that first served them. This allows you to shard data across the instances of a service. Best illustrated with an example. Suppose you have a service called `myService` and right now, it has 3 instances serving trafic. Invoking the service like so repeatedly ```bash $ lever invoke /myService/someMethod ``` ... will cause the requests to be sprinkled onto all 3 instances, with no guarantees of where it might land next. But if we specify a resource as part of the invokation like so ```bash $ lever invoke /myService/shinyResource/someMethod ``` ... then we are guaranteed that each time the request will be handled by the same instance every time. This allows you to cache relevant information about that resource in the instance's memory. The next time that resource is invoked you will be able to reuse the cached data. The resource identifier can be any string. If Lever has never seen that identifier before it will bind it with an instance on the spot. Subsequent requests for that identifier will be routed to the same instance. Although service and method names may not contain `/`, resource identifiers may. This allows you to create your own URL structure for resources belonging to the same service. [block:image] { "images": [ { "image": [ "https://files.readme.io/v8yvggdiRNOabLRPnoxM_sharding.png", "sharding.png", "1587", "1234", "#940d0d", "" ], "caption": "A resource invokation is routed to a specific instance" } ] } [/block] [block:callout] { "type": "warning", "title": "Important", "body": "Routing resources to the same instance is only guaranteed as long as that instance remains up. Lever OS may at any time stop that particular instance, which will cause that resource to be allocated to a different instance. Your implementation should handle this situation gracefully." } [/block] # Handling resource invokations Although each resource is handled by one instance at a time, each instance may handle more than one resource. It is the responsibility of the implementation of the methods to make the distinction when handling the request. The request identifier is typically passed as the first parameter (before the rest of the args) to the handling function - but you should consult the API reference for the language you are working with. It is always a good idea to validate and sanitize resource identifiers. This is because for many public-facing services a rogue client can choose any resource string it wants, potentially causing injection attacks if not properly sanitized. To help with managing resources on each instance, you can implement the methods below. ### :arrow-right: `NewResource(resourceName)` *optional* * `resourceName` is the resource identifier. * **Returns** `null`. This Lever method is invoked by the Lever OS subsystem when a resource is linked to the instance handling this call. The `NewResource` invokation is guaranteed to be called before any invokation belonging to that resource is called. ### :arrow-right: `CloseResource(resourceName)` *optional* * `resourceName` is the resource identifier. * **Returns** `null`. This Lever method is invoked by the Lever OS subsystem when a resource is unlinked from the instance handling this call. The `CloseResource` invokation is guaranteed to be called after all invokations belonging to that resource are called. [block:callout] { "type": "warning", "title": "Important", "body": "There is no guarantee that `CloseResource` is called every time. It is possible that the instance crashes or that Lever OS closes the instance before it has the opportunity to handle `CloseResource` calls." } [/block]