惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
U
Unit 42
IT之家
IT之家
Y
Y Combinator Blog
T
Tailwind CSS Blog
B
Blog
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
Jina AI
Jina AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
I
InfoQ
J
Java Code Geeks
F
Fortinet All Blogs
T
The Blog of Author Tim Ferriss
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Hackread – Cybersecurity News, Data Breaches, AI and More
人人都是产品经理
人人都是产品经理
腾讯CDC
Hugging Face - Blog
Hugging Face - Blog
GbyAI
GbyAI
博客园 - 司徒正美
The GitHub Blog
The GitHub Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
L
LangChain Blog

Ruby

一個用 DIDComm 實現服務器間通信的 Rails demo RubyConf China 2024 参会报告 - Day 1 有对 Ruby 感兴趣的吗? MRuby Devkit 一个简单的脚手架,帮助你像 Go 一样把 Ruby 编译成可执行二进制文件 使用 Ruby-build 在 MacOS 上 编译 Portable Ruby [翻译] Async Ruby(异步 Ruby) [翻译] Ruby Fiber Scheduler Ruby 3.2.0 发布 Ruby on Mac 用 100 行 Ruby 代码模拟 JavaScript 的 Eventloop 管窥蠡测从思考游戏到实现 2048 用 Ruby 讲从创业到 996 公司的故事(戏说 master-worker 模式) Sinatra 源码分析 (一):set 系统工作原理 《Ruby 设计模式》笔记 Ruby 标准库有趣部分摘要 并行并发进程线程协程 GIL 概念简明解释笔记(Ruby 举例) Sinatra 的 app 模板,提供一些胶水代码支持类似 Rails 的体验 Ruby 的方法查找再往前一步 有在深圳至简天成的吗? 求加微信 Ruby 3.0.0 Released 新建了个 ruby 中文讨论群 Language Hopping, Ruby 为什么不火,一点瞎想 ruby,一代优秀语言就这样陨落了吗? ruby 的 "a" 和 :a 能转换吗 求大佬帮安装一个 mastodon,有偿! notepad++ ssh 一些个小坑 有什么好的方法/IDE 阅读 Gem 库的源码? 问一个 ruby 的问题 用 discourse 搭了个论坛 求测试 找小伙伴一起开发和完善一个 Ruby 增量代码覆盖率统计工具
阿里云 OSS Ruby SDK 开发手记
rockuw · 2016-03-14 · via Ruby

阿里云 OSS是一个对象存储服务,类似于 Amazon 的 S3 。相比于自建存储,使用 OSS 能够迅速帮您搞定存储,并且大大地节省成本,提升可靠性和安全性。

现在,喜欢 Ruby 的同学终于可以优雅地使用 OSS 了。先看看 Rubyist 如何上传和下载文件吧:

require 'aliyun/oss'
bucket = Aliyun::OSS::Client.new(
  endpoint: 'http://oss-cn-hangzhou.aliyuncs.com',
  access_key_id: 'xxx',
  access_key_secret: 'yyy').get_bucket('bucket')

bucket.put_object('ruby') { |s| s << 'hello world' }
bucket.get_object('ruby') { |c| puts c }

bucket.put_object('rails', :file => '/tmp/x')
bucket.get_object('rails', :file => '/tmp/y')

是不是 so easy ? OSS SDK for Ruby 支持 OSS 目前绝大部分功能,主要的 highlights 包括:

  • 顾名思义的接口 put_object/get_object/list_buckets/list_objects
  • block 风格的代码
  • iterator 形式的列表
  • 流式上传 /下载
  • 断点续传上传 /下载

下面我们随便挑几个来聊一聊:

1. iterator 形式的列表

OSS 用户在一个 bucket 下可能有成千上万的 objects ,所以 OSS 不会将 object 列表一次性全部返回,每次最多返回 1000 条。如果我要列出前 1001 个 object 怎么办?一般来说用户可能要调用两次接口。但是在 ruby 中你只需要一行:

bucket.list_objects.take(1001)

再比如用户要找 files/下文件名包含'ruby'的文件:

bucket.list_objects(prefix: 'files/').find { |x| x.key.include?('ruby') }

是不是非常方便?

2. 流式上传

流式上传允许用户动态地一边生成内容,一边上传到 OSS ,上传的数据可以 generated on the fly 。如下面的例子:

bucket.put_object('numbers') do |stream|
  (1..1_000_000).each { |i| stream << i << "\n" }
end

注意:这里并不是要 100 万个数字都生成完后再发送,而是一边生成一边发送的。

要做到上面的效果并不容易,试想一下,put_object要如何调用所接受的 block 参数?如果调用那么 100 万个数字都一口气生成完了,所以,如何能做到对一个函数调用一半? 答案就是使用Fiber

def hello
  puts 'hello'
  Fiber.yield
  puts 'world'
end

def world
  fiber = Fiber.new { hello }

  puts 'first'
  fiber.resume # puts 'hello'
  puts 'second'
  fiber.resume # puts 'world'
end

world

类似上面的代码,stream#<<内每接受一部分内容,会将自己 yield 出去,这样已经接受的内容就可以立即发送出去。有兴趣可以查看SDK 代码

3. 断点上传

在上传大文件时如果中途失败了,要重新上传是不是很沮丧?有了断点上传,中途失败后可以接着上次的进度继续上传。在 ruby 中只需要:

bucket.resumable_upload('object_key', 'local_file')

断点上传依赖于 OSS 提供的 multipart 功能,类似于一个事务:

  • 开启一个 multipart 上传 (begin transaction)
  • 将文件分成多个 part 分别上传 (do modify)
  • 完成此次 multipart 上传 (commit transaction)

只有最后一步成功后文件才算上传成功,在此之前文件对用户是不可见的。

文件被中断后如何恢复上传?如何知道哪些 parts 已经上传成功?这需要记录事务的状态信息。 SDK 的做法是将这些信息(称为 checkpoint )保存在一个本地的 json 文件中。每上传完一个 part 就更新一次 checkpoint 。恢复上传时从 checkpoint 文件中恢复上传的进度。

另外断点上传 /下载中也利用多线程实现加速,先看结果:

$ruby tests/test_large_file.rb -n test_large_file_1gb                                                                                                                                                     
Run options: -n test_large_file_1gb --seed 7587

# Running:

                                       user     system      total        real
Upload with put_object:           20.810000   1.880000  22.690000 ( 62.843336)
Upload with resumable_upload:     28.720000   9.740000  38.460000 ( 33.963555)
Download with get_object:         17.300000   4.550000  21.850000 ( 47.132476)
Download with resumable_download:  23.260000   9.530000  32.790000 ( 31.883211)

Ruby 或者 Python 的多线程一直是个“迷”,但是对于这种 IO 多场景,用多线程效果还是很明显的。因为进行 IO 的标准库函数在需要等待 IO 时会将当前线程切出去。参考: http://yehudakatz.com/2010/08/14/threads-in-ruby-enough-already/

一个简单的 demo

借助 rails ,可以在 15 分钟内搭建一个oss 文件管理器,可以查看 /上传 /下载文件,效果图如下:

QQ20151202_0

更多