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

推荐订阅源

人人都是产品经理
人人都是产品经理
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy International News Feed
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
Spread Privacy
Spread Privacy
The Hacker News
The Hacker News
P
Palo Alto Networks Blog
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
Google Online Security Blog
Google Online Security Blog
H
Heimdal Security Blog
N
News | PayPal Newsroom
Attack and Defense Labs
Attack and Defense Labs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园 - 【当耐特】
Webroot Blog
Webroot Blog
小众软件
小众软件
Help Net Security
Help Net Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
N
News and Events Feed by Topic
Hacker News - Newest:
Hacker News - Newest: "LLM"
PCI Perspectives
PCI Perspectives
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Cloudflare Blog
Cloudbric
Cloudbric
AI
AI
WordPress大学
WordPress大学
博客园 - 聂微东
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
Hacker News: Ask HN
Hacker News: Ask HN
H
Hacker News: Front Page
博客园 - Franky
V
V2EX
Schneier on Security
Schneier on Security
G
GRAHAM CLULEY
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
H
Help Net Security
量子位
S
Security @ Cisco Blogs
大猫的无限游戏
大猫的无限游戏
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Recorded Future
Recorded Future
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
C
Cisco Blogs
S
Security Affairs

Yesterday17's Blog

2026 新年解密红包 / Melody Flag | Yesterday17's Blog 谈谈 Iori 的设计思路(二):如何实现一个 Showroom 录制工具? | Yesterday17's Blog 谈谈 Iori 的设计思路(一):从 Nico Timeshift 说起 | Yesterday17's Blog Iori Minyami 0.1.0 发布 | Yesterday17's Blog 2025 新年解密红包 / Melody Flag | Yesterday17's Blog 使用 Cloudflare Warp 解决罗森票务的海外登录问题 | Yesterday17's Blog How To Blog 04: The Astro v5 Era | Yesterday17's Blog 谈谈 tokio::select! 的公平性 | Yesterday17's Blog Learning Pingora 05 - Connect with TLS | Yesterday17's Blog Leaving Bytedance | Yesterday17's Blog 大橋彩香 AsiaTour「Reflection」上海公演 个人向记录 & Repo | Yesterday17's Blog Recoving from burnout - What happened? | Yesterday17 Yubikey 重建手册 | Yesterday17's Blog How To Blog 03: Heimus | Yesterday17's Blog 🪧 Blog Migration Accouncement | Yesterday17's Blog Learn Your IDE - VSCode 是如何仅重启插件的? | Yesterday17's Blog How To Blog 02: Astro❤️Password | Yesterday17's Blog How To Blog 01: Why, How, and the Future | Yesterday17's Blog Learning Pingora 04 - Establish L4 Connection | Yesterday17's Blog Learning Pingora 03 - Upstreams and Peers | Yesterday17's Blog Learning Pingora 02 - A Simple HTTP Server | Yesterday17's Blog Learning Pingora 01 - Getting Started | Yesterday17's Blog 2024 新年解密红包 / Melody Flag | Yesterday17's Blog 向新的一年飞驰——记录 2023 | Yesterday17's Blog 「サクラノ刻」对话选摘(2) | Yesterday17's Blog PGP Key Revocation 注销声明 | Yesterday17's Blog 「サクラノ刻」对话选摘(1) | Yesterday17's Blog 2023 新年解密红包 / Melody Flag | Yesterday17's Blog 『蒼の彼方のフォーリズム』通关感想 | Yesterday17's Blog 单显卡直通教程 | Yesterday17's Blog 对博客与笔记的思考 | Yesterday17's Blog Project Anni 之旅(3)自动化 Flutter 应用 CI/CD 上架流程 | Yesterday17's Blog AsobiStage 直接播放链接 | Yesterday17 如何在后分P时代进行投稿——sswa使用详解 | Yesterday17's Blog JSON RPC 与 LSP 协议基础 | Yesterday17's Blog Grajapa Shueisha / BookEnd 加密方式调查 | Yesterday17's Blog 【2022篇+WriteUp】如何再收一个新年红包? | Yesterday17's Blog 如何将良心云的良心功能清理干净 | Yesterday17's Blog 【油猴脚本】bilibili 投稿页面返回旧版+旧版页面强制允许分P上传 | Yesterday17's Blog Cloudr1v1 授权方式分析 | Yesterday17 Typora 1.0.2 逆向实录 | Yesterday17's Blog Project Anni 之旅(2)ValueAfterTable——toml-rs的实现与限制 | Yesterday17's Blog IPv4透明代理+IPv6 Passthrough——树莓派单臂软路由折腾记 | Yesterday17's Blog Chaos; Child 汉化补丁 神秘编码探索 | Yesterday17's Blog 镣铐与舞蹈——个性与共性之迷思 | Yesterday17's Blog Go 学习笔记 02 - 找准 io 之道 | Yesterday17's Blog NAT Slipstreaming v1 原理浅析 | Yesterday17's Blog 绕过「9-nine-」的 CDKEY 验证——KrkrPlugin 正(?)向实录 | Yesterday17's Blog 静流的青春纪念册——「サクラノ刻 -櫻の森の下を歩む-」体验版感言 | Yesterday17's Blog Project Anni 之旅 01 - 从 clap-builder 到 derive | Yesterday17's Blog [Google CTF 2021] CPP WriteUp | Yesterday17's Blog 获取 アソビステージ 的实际播放链接 | Yesterday17's Blog 90 行 Rust 代码实现 AsyncTeeReader | Yesterday17's Blog 或许还算有价值一读的文章列表 | Yesterday17's Blog 从零开始的 Seedbox 之旅 | Yesterday17's Blog [随笔]技术型博客行文迷思(1) | Yesterday17's Blog 浅谈 git fetch 的工作方式 | Yesterday17's Blog 『ソーサレス*アライヴ! ~the World's End Fallen Star~』通关感想" | Yesterday17's Blog Rust std::fmt 格式语法简述 | Yesterday17's Blog 日亚修改居住国的解决方案 | Yesterday17's Blog [Windows/Linux] GC553 的 Switch 完美采集之路 | Yesterday17's Blog 【翻译】Subtyping and Variance / 子类型与变型 | Yesterday17's Blog Berd's Red Envelope 2021 WriteUp | Yesterday17's Blog 【中英对照】ALSA 音频 API 使用教程/A Tutorial on Using the ALSA Audio API | Yesterday17's Blog 从 cue_scanner.l 看 CUE Sheet 的词法单元 | Yesterday17's Blog Postman 历史记录导出的解决方案 | Yesterday17's Blog 《恋爱绮谭 不存在的夏天》通关感想 | Yesterday17's Blog [微机实验/TD-PITE] 微机接口综合实验 | Yesterday17's Blog [微机实验/TD-PITE] 键盘扫描及数码管显示实验 | Yesterday17's Blog [微机实验/TD-PITE] 数码管显示实验 | Yesterday17's Blog Airsonic Advanced+Google Drive+Caddy 部署纪实 | Yesterday17's Blog X-NUCA 2020 - hellowasm 题解 | Yesterday17's Blog [微机实验/TD-PITE] 8251 串行接口实验 | Yesterday17's Blog Node.js child_process.fork 与 env 污染 RCE | Yesterday17's Blog EP.01 「夜の向日葵」 | Yesterday17's Blog [微机实验/TD-PITE] 8254 定时/计数器实验+选做实验 | Yesterday17's Blog [JLU CTF/2020] babywasm WriteUp | Yesterday17's Blog PHP 反序列化与经典利用 | Yesterday17's Blog WebAssembly 逆向简述 | Yesterday17's Blog 『彼女、お借りします』一期完结点评 | Yesterday17's Blog [微机实验/TD-PITE] D/A 转换实验+选做实验 | Yesterday17's Blog [微机实验/TD-PITE] A/D 转换实验+选做实验 | Yesterday17's Blog 开源项目申请 JetBrains Open Source License 简单流程 | Yesterday17's Blog 微软拼音与 JetBrains 搜索快捷键冲突的解决方案 | Yesterday17's Blog [微机实验/TD-PITE] 8259 中断优先级实验+选做实验 | Yesterday17's Blog IFTTT 测试(续) | Yesterday17 IFTTT 测试 | Yesterday17's Blog [微机实验/TD-PITE] 存储器扩展实验+选做实验 | Yesterday17's Blog 新版 GCC 针对 -fdump-translation-unit 的替代方案 | Yesterday17's Blog 一次 HSTS 策略配置的排错之旅 | Yesterday17's Blog YukiNative 踩坑记——Windows 的消息队列 | Yesterday17's Blog 我是我自己——论获取 HTTPS 证书时的验证步骤 | Yesterday17's Blog 【设计文档】对 PUG 的大规模设计修订(1.1) | Yesterday17's Blog GS65 折腾记(2)加装固态,分区,Grub2 引导 Manjaro LiveCD | Yesterday17's Blog 「さくら、もゆ。」的空白字体列表——一次逆向问题定位过程实录 | Yesterday17's Blog GSuite 探索篇(1)使用 Service Account 向 Google Drive 传输文件 | Yesterday17's Blog 『サクラノ詩 -櫻の森の上を舞う-』通关感想 | Yesterday17's Blog 《ATRI -My Dear Moments-》通关感想 | Yesterday17's Blog [工具][VSCode 扩展] AegiKit——方便 Aegisub 使用的工具箱 | Yesterday17's Blog 贝塞尔曲线、字体矢量化与曲线运算 | Yesterday17's Blog
【设计文档】PUG 的基本构成单元——Workflow、Pipeline 和 Pipe(1.0) | Yesterday17's Blog
Yesterday17 · 2020-04-05 · via Yesterday17's Blog

PUG 已废弃,设计文档仅供参考。


本文档是关于自动搬运系统 PUG 的设计文档,在一定程度上消除了先前讨论中的术语分歧,并试图以简单易懂的方式解释整个系统预计的工作流程。

PUG

PUG 名起自《水瀬いのりと大西沙織のPick Up Girls!》[1],是试图解决单次视频搬运不定时、步骤繁多,但多次搬运视频步骤相同、重复劳动的产物。PUG 目前的计划项目有:

  • pug:本体,负责主体逻辑。
  • pugc:Electron 客户端,负责在个人使用时提供简单易用的用户界面。
  • pug-web-extension:浏览器插件,负责在浏览器段提供易用的用户界面。
  • pugw-frontend:前端页面,负责与服务器上的后端对接,提供托管的搬运业务。该项目属于多人课设项目(据说),并计划将该项目的界面应用到其余两个客户端中。

同时,因 PUG 而废弃的项目有:

  • [u2b](https://github.com/Yesterday17/u2b):试图自动搬运 YouTube 视频到 bilibili 的项目,其功能是 PUG 的子集,故废弃。
  • [bili-archive](https://github.com/Yesterday17/bili-archive) 及其衍生项目(包括 [bili-archive-frontend](https://github.com/Yesterday17/bili-archive-frontend)[bili-archive-helper](https://github.com/Yesterday17/bili-archive-helper)[bili-archive-report](https://github.com/Yesterday17/bili-archive-report)):其功能相当于从 bilibili 搬运视频到本地,功能亦为 PUG 的子集,故废弃。

值得注意的是,虽然该项目的起因是搬运视频,但设计中并没有局限于视频本身。理论上只要有模块支持,PUG 也能完成自动诸如搬运推文等非视频性工作。

总览

下面我们给出一张单个 Work 工作的流程图。这张图看起来可能有点像固定管线,但其实这些分块只是为了描述这条 Workflow 的工作流程而做出的人为划分,实际过程中并不存在强制的步骤关系。

总览:PUG 的基本工作流程
总览:PUG 的基本工作流程

我们注意到,我们称整个工作为一个 Work,工作在 Workflow 中运行,因此这张图描绘的是 Workflow 的一个缩影;图中右边四列都是 Pipeline,而 Workflow 就是一个从左至右的过程,这表明了一个 Workflow 的设计意图是用来完成一种任务,本质不同的两类任务应该分成两个不同的 Workflow;代表 Pipeline 框中有许多蓝色的 Pipe,这表明了 Pipe 应该是用来完成某一项具体任务的最小单位

针对 Pipe,我们的单位是“”;针对 Pipeline,我们的单位是“”;针对 Work,我们的单位是“”;而针对 Workflow,我们的单位是“”。

整个理解过程中,如果你有不明白的地方,可能需要多次回来观察这张图片,这张图片描绘了 PUG 运行的基本流程。下文为了简单期间,会将这张图简称为总览图

Pipe

正如上文所说,Pipe 是完成某一项任务的最小单位,这是狭义的 Pipe 定义;从广义上来说,Pipe 是整个系统中的通用结构单元,Pipeline 和 Workflow 本质上也是 Pipe,只不过其并不满足狭义上 Pipe 的定义。当然了,广义上的 Pipe 属于实现细节,在后文的叙述中,如无特殊说明,Pipe 一般均指狭义上的 Pipe

把任务拆分成 Pipe,也就是为最小单位,是有原因的。设想下面这种情景:在一个 Workflow 中,我们可能需要多次登录某一网站。登录的目的是为了重新获取被注销的用户账户的用户凭据,因此在每次用户登录失效时都需要重新登录。那假如我们将登录的任务和上传的任务实现在了一起,那么我们就无法完成单独的登录功能了。

上面的案例对应的是总览图中的最右边一列,图中对应用户账户登录失效的处理措施是用户干预,而用户干预的一般用途是要求用户输入对应的凭据,即用户名和密码。在用户干预完成后,势必需要登录操作,因此将登录操作单独拆分称 Pipe 是有必要的。

Pipe 是没有状态的,它的状态由上层管理,其本身只存在属性。属性代表了 Pipe 的基本性质,一般情况下不应该发生改变。

Pipeline

Pipe 的功能的确很细致,细致到我们常常不需要那么细致的操作,因此出现了 Pipeline。一条 Pipeline 对应的是一些 Pipe 的组合,它组合了这些操作,并成为了高一级的复用单元,我们称 Pipeline 是用户态的复用单元

还是以上文的登录情景为例:验证用户凭据是否有效很显然是一个 Pipe,而需要用到用户凭据认证的情况有很多,除了无效时重新登录之外,还有很多有效时的操作,如获取 Timeline、获取关注列表等,而每一个上述的操作都会用到验证用户凭据这一节 Pipe。这时候,我们就可以将验证用户凭据的 Pipe对应的操作 Pipe 组合成一条 Pipeline,以便在 Workflow 中使用。

这里可能会有读者对 Pipeline 的功能表示不解。确实,在简单流程下 Pipeline 的作用可能不大,但当 Workflow 存在非线性流程,或存在多个 Workflow 时,其可能就会需要复用一些相同的单元,而 Pipeline 就代表了这样的复用单元。

此外,Pipeline 的用户态复用性还意味着其可以作为一个处理部分被打断,被打断后,Pipeline 不会保存其中的任何内容,相当于该 Pipeline 未被执行。

和 Pipe 一样,Pipeline 也是没有状态的。

Workflow

Workflow 是多条 Pipeline 按照一定逻辑执行直至结束的流程体现,大多数用户态的操作都针对 Workflow 完成,比如输入、暂停、中止等。此外,全系统的状态也由 Workflow 管理。

为了控制 Workflow 的流程,我们计划引入一些特殊的 Pipeline。区别于普通的单输入单输出的 Pipeline,它们可以拥有复数输入复数输出,以完成特定的应用目标。(draft)