{"action":"created","issue":{"url":"https://api.github.com/repos/libgit2/rugged/issues/528","labels_url":"https://api.github.com/repos/libgit2/rugged/issues/528/labels{/name}","comments_url":"https://api.github.com/repos/libgit2/rugged/issues/528/comments","events_url":"https://api.github.com/repos/libgit2/rugged/issues/528/events","html_url":"https://github.com/libgit2/rugged/pull/528","id":109679837,"number":528,"title":"WIP: Better Backend Support","user":{"login":"arthurschreiber","id":2195,"avatar_url":"https://avatars.githubusercontent.com/u/2195?v=3","gravatar_id":"","url":"https://api.github.com/users/arthurschreiber","html_url":"https://github.com/arthurschreiber","followers_url":"https://api.github.com/users/arthurschreiber/followers","following_url":"https://api.github.com/users/arthurschreiber/following{/other_user}","gists_url":"https://api.github.com/users/arthurschreiber/gists{/gist_id}","starred_url":"https://api.github.com/users/arthurschreiber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arthurschreiber/subscriptions","organizations_url":"https://api.github.com/users/arthurschreiber/orgs","repos_url":"https://api.github.com/users/arthurschreiber/repos","events_url":"https://api.github.com/users/arthurschreiber/events{/privacy}","received_events_url":"https://api.github.com/users/arthurschreiber/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2015-10-04T12:46:27Z","updated_at":"2015-10-05T21:05:05Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/libgit2/rugged/pulls/528","html_url":"https://github.com/libgit2/rugged/pull/528","diff_url":"https://github.com/libgit2/rugged/pull/528.diff","patch_url":"https://github.com/libgit2/rugged/pull/528.patch"},"body":"Initial backend support was added by @charypar as part of #410.\r\n\r\nUnfortunately, the implementation is a bit convoluted: Every backend implementation needs to `include <rugged.h>` to get the definition of `rugged_backend`. Also, the way backends are implemented right now, they always need to provide a `refdb` and `odb` backend together, there's no way to use e.g. one backend type for the odb and another backend type for the refdb. Also, config backends were missing completely.\r\n\r\nThis PR is aimed at fixing those shortcomings and make backend support first class.\r\n\r\nIt introduces a few new classes that wrap existing functionality from libgit2, provides abstract implementations of custom refdb, odb and config backends and exposes new APIs on the `Repository` object to make it easier to initialize repositories with custom backends.\r\n\r\n---\r\n\r\n- [x] Add `Rugged::Refdb` to wrap `git_refdb` functionality from `libgit2`.\r\n- [x] Add `Rugged::Refdb::Backend::FileSystem` to expose `git_refdb_backend_fs` and to serve as an example on how to wrap `git_refdb_backend`.\r\n- [ ] Add `Rugged::Refdb::Backend::Custom` as an abstract base class that can be extended to provide new refdb backends that are defined using Ruby code.\r\n- [x] Add `Rugged::Odb` to wrap `git_odb` functionality from `libgit2`.\r\n- [ ] Add `Rugged::Odb::Backend::Loose`, `Rugged::Odb::Backend::Packed` and `Rugged::Odb::Backend::Single` to expose `git_odb_backend_loose`, `git_odb_backend_packed` and `git_odb_backend_single` and to serve as examples on how to wrap `git_odb_backend`.\r\n- [ ] Add `Rugged::Odb::Backend::Custom` as an abstract base class that can be extended to provide new odb backends that are defined using Ruby code.\r\n- [ ] Add `Rugged::Config::Backend::Custom` as an abstract base class that can be extended to provide new config backends that are defined using Ruby code."},"comment":{"url":"https://api.github.com/repos/libgit2/rugged/issues/comments/145668202","html_url":"https://github.com/libgit2/rugged/pull/528#issuecomment-145668202","issue_url":"https://api.github.com/repos/libgit2/rugged/issues/528","id":145668202,"user":{"login":"charypar","id":1517854,"avatar_url":"https://avatars.githubusercontent.com/u/1517854?v=3","gravatar_id":"","url":"https://api.github.com/users/charypar","html_url":"https://github.com/charypar","followers_url":"https://api.github.com/users/charypar/followers","following_url":"https://api.github.com/users/charypar/following{/other_user}","gists_url":"https://api.github.com/users/charypar/gists{/gist_id}","starred_url":"https://api.github.com/users/charypar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/charypar/subscriptions","organizations_url":"https://api.github.com/users/charypar/orgs","repos_url":"https://api.github.com/users/charypar/repos","events_url":"https://api.github.com/users/charypar/events{/privacy}","received_events_url":"https://api.github.com/users/charypar/received_events","type":"User","site_admin":false},"created_at":"2015-10-05T21:05:05Z","updated_at":"2015-10-05T21:05:05Z","body":"Great to see this being extended! Looks good. \r\n\r\n@arthurschreiber How do you plan to implement the support for backends implemented in ruby? I believe that support was originally included in Rugged (I can try and dig out an old commit I found last time I looked), but was later removed for performance reasons – there was too much context switching (too many indirections) between ruby and C on every read and write to make backends written in Ruby practical (e.g. for Redis, it would be something like `Client ruby code -> Rugged -> C rugged -> libgit -> abstract backend -> rugged backend -> ruby backend implementation -> ruby redis client -> redis native lib`).\r\n\r\nThat's also the reason why I've done the backends the way they are implemented, because they only get injected from Ruby code, but the reads and writes are all performed in native land as if you were using libgit and the backend library directly.\r\n\r\nDid you come up with a better solution for this?"}}