{"id":19885646,"url":"https://github.com/asmod4n/mruby-io_uring","last_synced_at":"2025-03-01T03:47:16.585Z","repository":{"id":231420352,"uuid":"781336438","full_name":"Asmod4n/mruby-io_uring","owner":"Asmod4n","description":"io_uring for mruby","archived":false,"fork":false,"pushed_at":"2025-02-15T08:32:13.000Z","size":406,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-15T09:25:53.140Z","etag":null,"topics":["io-uring","linux","mruby","mruby-gem","ruby"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Asmod4n.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-03T07:32:31.000Z","updated_at":"2025-02-15T08:32:16.000Z","dependencies_parsed_at":"2024-11-10T14:27:40.851Z","dependency_job_id":"1b552e6a-3a63-41ae-956e-c8025fdc7323","html_url":"https://github.com/Asmod4n/mruby-io_uring","commit_stats":null,"previous_names":["asmod4n/mruby-io_uring"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asmod4n%2Fmruby-io_uring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asmod4n%2Fmruby-io_uring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asmod4n%2Fmruby-io_uring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asmod4n%2Fmruby-io_uring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Asmod4n","download_url":"https://codeload.github.com/Asmod4n/mruby-io_uring/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241313181,"owners_count":19942417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["io-uring","linux","mruby","mruby-gem","ruby"],"created_at":"2024-11-12T17:35:10.289Z","updated_at":"2025-03-01T03:47:16.566Z","avatar_url":"https://github.com/Asmod4n.png","language":"C","readme":"# mruby-io_uring\n\nio_uring for mruby (WIP)\n\nRequirements\n============\nThis is only working with a linux kernel.\n\nInstallation\n============\nThe gem is called mruby-io-uring for adding it to your project, here is an example.\n\n```ruby\nconf.gem mgem: 'mruby-io-uring'\n```\nto add it to your build_config.rb\n\nSince there are numerous versions of liburing around we are shipping a version which is compatible with this gem.\n\nString ownership\n----------------\n\nFunctions which end in _fixed use a internal and private buffer pool, those buffers are mruby Strings and belong to the ring, not to you, they are frozen at all times and you musn't change their contents.\n\nWhen you are done with a fixed buffer you have to return them to the ring with ring.return_used_buffer(operation), take a look at the file_benchmark.rb in the example dir for a example.\nPerformance of _fixed functions can be much higher.\n\nEvery other function which takes a string argument freezes that string till io_uring has processed it and given back to you in a ring.wait block, where its unfrozen. If you gave the ring a frozen string, it returns frozen back to you.\n\n\nHere is an example on how to use them (requires mruby-phr for http parsing)\n-------------------------------------\n```ruby\nbody = \"hallo\\n\"\nheaders = \"HTTP/1.1 200 OK\\r\\nConnection: keep-alive\\r\\nContent-Type: text/plain\\r\\nContent-Length: #{body.bytesize}\\r\\n\\r\\n\"\nresponse = \"#{headers}#{body}\"\nuring = IO::Uring.new\nserver = TCPServer.new(12345)\nserver.listen(4096)\nuring.prep_multishot_accept(server)\n\nphr = Phr.new\n\nwhile true\n  uring.wait do |operation|\n    raise operation.errno if operation.errno\n    case operation.type\n    when :multishot_accept\n      puts \"Remote Address: #{operation.to_io.remote_address.inspect}\"\n      puts \"Socket        : #{operation.res}\"\n      uring.prep_recv(operation.res)\n      #operation.res  is the accepted socket\n      #operation.sock is the socket passed to prep_accept, aka the server socket.\n    when :recv\n      next if operation.res == 0\n      ret = phr.parse_request(operation.buf)\n      case ret\n      when :incomplete, :parser_error\n        uring.prep_close(operation.sock)\n        phr.reset\n        next\n      when Integer\n        puts \"HTTP Method   : #{phr.method}\"\n        puts \"HTTP Version  : 1.#{phr.minor_version}\"\n        puts \"HTTP Path     : #{phr.path}\"\n        puts \"HTTP Headers  : #{phr.headers.inspect}\"\n        puts \"HTTP Body     : #{operation.buf.byteslice(ret..-1).inspect}\"\n      end\n      phr.reset\n      uring.prep_send(operation.sock, response)\n    when :send\n      uring.prep_close(operation.sock)\n    end\n  end\nend\n```\n\nuring.wait accepts two arguments, the number of operations to wait for, by default 1, and a timeout as a float value, if a timeout occurs false is returned.\n\n\nAPI Docs\n========\n\nIO::Uring::OpenHow.new(flags = nil, mode = 0, resolve = nil)\n\n### Supported Flags\n\n- `r`: `O_RDONLY` (read-only)\n- `w`: `O_WRONLY | O_CREAT | O_TRUNC` (write-only, create file if not exists, truncate if exists)\n- `a`: `O_WRONLY | O_CREAT | O_APPEND` (append, create file if not exists)\n- `+`: `O_RDWR` (read and write, must follow `r`, `w`, or `a`)\n- `e`: `O_CLOEXEC` (close file descriptor on exec)\n- `s`: `O_SYNC` (synchronize)\n- `d`: `O_DIRECT` (direct access)\n- `t`: `O_TMPFILE` (temporary file)\n- `na`: `O_NOATIME` (do not update access time)\n- `nc`: `O_NOCTTY` (do not assign controlling terminal)\n- `nf`: `O_NOFOLLOW` (do not follow symbolic links)\n- `nb`: `O_NONBLOCK` (non-blocking)\n- `x`: `O_EXCL` (error if file exists)\n- `D`: `O_DIRECTORY` (must be a directory)\n- `P`: `O_PATH` (resolve pathname, do not open file)\n\n### Supported Resolve\n\n- `L`: `RESOLVE_NO_SYMLINKS` (do not follow symbolic links)\n- `X`: `RESOLVE_NO_XDEV` (do not resolve across filesystem boundaries)\n- `C`: `RESOLVE_CACHED` (use cached resolution)\n- `B`: `RESOLVE_BENEATH` (resolve only beneath the directory)\n- `R`: `RESOLVE_IN_ROOT` (perform resolution in root directory)\n\nOperations\n==========\n\nUsing a ring.prep function retuns you an operation which is about to be send to the ring when you call ring.wait,\nthat operation has operation.userdata and opration.userdata= functions which you can use however you like.\nOne example is turning a created tcp socket into a ruby TCPSocket object and storing that as the userdata for said operation.\n\n```ruby\noperation = ring.prep_socket(Socket::AF_INET, Socket::SOCK_STREAM, 0)\nring.wait do |operation|\n    operation.userdata = operation.to_io\nend\n```\n\nThat way, you can do some socket operations which aren't implemented in this gem directly with the methods mruby gives you for a TCPSocket, any time you need it, like operation.userdata.remote_address to get the Addrinfo of the server you have connected to.\nWhen using functions which swap out the operation you gave it the userdata is retained.\n\nWe check what type the underlaying socket is and give you a appropiate one back, be aware, you only gain TCPServer and UNIXServer objects back when the sockets are accepting connections, so you have to wait after you called prep_accept on them to gain the correct type.\n\n\nLICENSE\n=======\nCopyright 2024, 2025 Hendrik Beskow\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this project except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasmod4n%2Fmruby-io_uring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasmod4n%2Fmruby-io_uring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasmod4n%2Fmruby-io_uring/lists"}