前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Serverless实战:打造个人阅读追踪系统

Serverless实战:打造个人阅读追踪系统

作者头像
ThoughtWorks
发布于 2018-04-13 10:10:45
发布于 2018-04-13 10:10:45
1.3K00
代码可运行
举报
文章被收录于专栏:ThoughtWorksThoughtWorks
运行总次数:0
代码可运行

阅读习惯和个人知识管理体系

进入互联网时代,知识的获取成本变得前所未有的低廉,但是无论再好的知识,若是没有对个人产生价值的话,那也只不过是一种信息噪音而已。

我在《个人知识管理:知识的三种形态》这篇文章中使用“材料 -> 资料 -> 知识”这样的路径来诠释信息的流通,如何方便快捷并且有效地收集材料,再将其整理转化为有价值的个人知识体系结构,在这个信息极度碎片化的时代变得尤为重要。而在《去伪存真的知识管理之路》一文中也详细阐述了如何将网络上的碎片化文章纳入统一的稍后阅读体系,比如有时候在朋友圈看到一篇好文章,但暂时没时间直接看,或是这篇文章值得再读一遍,细读一遍,那么我就会将其存入稍后阅读工具即Instapaper当中,诸如此类的还有Pocket、收趣等等。

稍后阅读中永远读不完的痛点:缺乏追踪

随着时间的推移,Instapaper里面的文章将会变得越来越多,就像我们在代码中所注释的TODO:可能就变成了Never Do,“稍后读”也是一样地被广为诟病:Read it Later=Read Never。

其实我发现文章堆积的一个永恒痛点就是没有有效的方式追踪自己的阅读需求与能力,其核心原因在于阅读的速度赶不上添加的速度。从而没办法可视化的评估阅读进度、合理安排阅读计划,也就没办法给予自己适当的奖励,长此以往必然将失去阅读的动力。

在之前的一篇文章——《基于GitHub的敏捷学习方法之道与术》,其中提到使用GitHub Issue来管理自己的学习计划,于是就产生了这么一个想法——将我的稍后阅读列表跟GitHub结合起来,使用ZenHub丰富的图表功能将阅读体系进行追踪与可视化。


可视化Cumulative Flow Diagram

首先让我们直接来看一下最终的具体效果图,在这里简单介绍一下CFD(Cumulative Flow Diagram)即累积流图,这是一种能让你快速了解项目或产品工作概况的图表,关注的是价值的流动效率,价值的流动最直接的体现就是需求卡片在各个队列中的数量。

里特定律(Little’s law)告诉我们,交付时间(Delivery time)依赖于在制品数量(Work In Progress, WIP)。WIP是指所有已经初始但还未完成的工作,例如:所有在分析(Analysis)与完成(Done)之间的工作。首先需要留意的就是WIP,如果WIP增加了,交付日期就会有风险。ZenHub所提供的Release Report中最有效果的就是预测完成日期,总之就是跟敏捷方法结合起来,使用项目管理的方式来管理自己的阅读列表,虽然我还处在进一步的探索之中,但是每次看到这个走势图就能对自己的阅读列表有更多的掌控和理解,至少减少了因文章堆积而产生的焦虑感。

IFTTT与Serverless架构

那么这是怎么通过APIs来实现的呢?在真正进入正题之前我们先来简单介绍一下Serverless架构。

Serverless指的是在构建Web应用程序的时候,不用担心如何配置服务器,但是这并不意味着应用程序不会在服务器上运行,而是说服务器的管理都可以尽可能地交给相应的云平台,从而最大程度地减轻开发人员的部署与配置工作。与之对应的一个名词可能就是Function As a Service(FAAS),由AWS Lambda这个命名就能想到,当我们在构建Serverless架构时,实际上我们是在写一个个的Function,即函数而已。

流程化:APIs即服务

首先让我们来介绍一下IFTTT即if this then that。通俗的来讲,IFTTT的作用就是当一件事情被触发时,能够执行设定好的另一件事。所谓的「事」,指的是各种应用、服务之间可以进行有趣的连锁反应。IFTTT的宗旨是Put the internet to work for you(让互联网为你服务)。用户可以在IFTTT里设定任何一个你需要的条件,当达成条件时,便会触发下一个指定好的动作。它就像是一座神奇的桥梁,能连接我们日常所用的各种网络服务。

而我们现在遇到的这个串联式的场景是特别合适Serverless架构的,使用IFTTT并且将它跟Instapaper账号绑定,设置文章添加、高亮、归档等行为作为trigger条件,然后将相关信息发到某一个指定API endpoint。先把操作GitHub Issue和ZenHub的各种APIs准备好,结合IFTTT的触发器与Marker工具能够非常方便地与之相集成,最后我们可以产出这样一个APIs交互流程图:

初始化Webtask项目

虽然AWS Lambda是Serverless架构的典范,但它也有一些槽点,而且我觉得已经被人说得足够多了,所以我们今天就来尝尝鲜,着重介绍和使用一下Webtask。你可能没有听说过推出该服务的这家公司——Auth0,但你一定知道大名鼎鼎的JWT即JSON Web Token,这是一种开放标准(RFC 7519),通常被运用在身份验证(Authentication)和信息交换等需要安全传输信息的场景下。

首先让我们来安装工具初始化项目以及注册账号,然后使用电子邮件进行登录:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm install -g wt-cli
wt init <YOUR-EMAIL>

创建项目目录,添加index.js文件并添加以下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = function (cb) {
  cb(null, 'Hello World');
}

然后在该目录中运行以下命令,进行应用程序部署之后,点击控制台中输出的URL就能看到编程史上最有名气、没有之一的HelloWorld!:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wt create index

Webtask的上下文绑定

Webtask有一个实用工具webtask-tools,可以将应用程序绑定到Webtask上下文,让我们将之前所export的简单函数修改为绑定到Webtask的Express app,然后就可以愉快地使用Express进行开发,一切就又回到了熟悉的轨道:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

require('./routes/reading')(app)

module.exports = Webtask.fromExpress(app)

Webtask context还有一个非常重要的用途,就是在部署时传输一些敏感信息,比如安全Token,从而在应用程序当中随时使用它们。下面的部署命令中--secret后面所传入的ACCESS_TOKEN都会在后续与GitHub和ZenHub APIs交互时被用到。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wt create index --bundle --secret GITHUB_ACCESS_TOKEN=$GITHUB_ACCESS_TOKEN 
--secretZENHUB_ACCESS_TOKEN=$ZENHUB_ACCESS_TOKEN --secret
ZENHUB_ACCESS_TOKEN_V4=$ZENHUB_ACCESS_TOKEN_V4
# ./routes/reading.js
module.exports = (app) => {
  app.post('/reading', (req, res) => {
    const { GITHUB_ACCESS_TOKEN, ZENHUB_ACCESS_TOKEN, ZENHUB_ACCESS_TOKEN_V4 } = req.webtaskContext.secrets
    }
}

使用GitHub Issue追踪阅读列表

IFTTT:添加Instapaper文章后自动创建GitHub Issue

得益于IFTTT非常丰富的第三方服务,IFTTT可以直接创建Instapaper与GitHub Issue相集成的Applet:If new item saved, then create a new issue - IFTTT,就可以在当Instapaper新增文章的时候,自动在GitHub所指定的仓库Issues · JimmyLv/reading中创建一个新的Issue并添加相应的标题、链接以及描述等相关信息。

但仅仅只是添加一个Issue还不够,这时候还需要将这个Issue加入到指定的Milestone以便利用ZenHub的图表功能,使用GitHub的Webhooks功能就可以轻松帮我们把Issue更新的状态转发到我们所指定的Webtask地址:

使用GitHub Webhook更新Issue的Milestone

所以我们的Webtask就需要处理GitHub Webhook所转发的POST请求,其中包括了Issue的类型和内容,在拿到'opened'即新建Issue类型的action之后我们可以对其进行相应的处理,即添加到Milestone当中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (action === 'opened') {
  fetch(`${url}?access_token=${GITHUB_ACCESS_TOKEN}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      milestone: 1
    })
  })

}

结合ZenHub的Milestone燃尽图我们可以清晰地看到剩余阅读量,并且能够跟理想中的阅读速度进行对比,从而判断自己什么时候能够全部读完所有的文章。可能有些小伙伴看到这里会有所疑问,这些所谓的Story Point是从哪儿来的呢?接下来就要提到我们将要集成的ZenHub API了。


集成ZenHub API:阅读可视化

更新Issue的估点和Release

GitHub Issue的任何变动都会触发Webhook,因此我们可以在Issue被加入Milestone之后再处理下一个'milestoned' action,即:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (action === 'milestoned') {
fetch(`https://api.zenhub.io/p1/repositories/${REPO_ID}/issues/${number}/estimate?access_token=${ZENHUB_ACCESS_TOKEN}`, {
  method: 'PUT',
  body: JSON.stringify({ estimate: 1 })
})
  .then(() => {
    return 
fetch(`https://api.zenhub.io/v4/reports/release/591dc19e81a6781f839705b9/items/issues?access_token=${ZENHUB_ACCESS_TOKEN_V4}`,
    {
       method: 'POST',
    })
  })
}

这样我们就完成了对每个GitHub Issue的估点,以及设置了对应的Release,接下来所有的变动都将体现在ZenHub的图表当中。

归档Instapaper文章后关闭GitHub Issue

说了这么多,不要忘了整个阅读系统最最核心的部分依然还是「阅读」啊!在众多的稍后阅读工具中我无比喜爱Instapaper并迟迟没有转到Diigo的原因就在于它优秀、简洁、纯粹的阅读体验,让人可以专注在阅读本身这件事情上,在被Pinterest收购之后更是将所有的诸如全文搜索、无限高亮/笔记、速读等Premium功能都变成了免费,岂不美哉?

那么在完成阅读归档之后,最后一步就是在GitHub当中将Issue关闭掉,但是IFTTT的GitHub服务并没有提供close Issue的接口,于是乎我们就只有利用IFTTT新推出的Maker自己创建一个,即将Instapaper规划作为一个IF trigger,然后用Maker发出一个Web请求,可以是GET、PUT、POST、HEAD、DELETE、PATCH或者OPTIONS之中的任何一种,你甚至还可以制定Content Type和Body。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
app.get('/reading', (req, res) => {
  const { GITHUB_ACCESS_TOKEN } = req.webtaskContext.secrets
  const title = req.query.title
  let keyword = encodeURIComponent(title.replace(/\s/g, '+'))

fetch(`https://api.github.com/search/issues?q=${keyword}%20repo:jimmylv/reading`)
  .then(data => {
    if (data.total_count > 0) {
  data.items.forEach(({ url, html_url }) =>
    fetch(`${url}?access_token=${GITHUB_ACCESS_TOKEN}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ state: 'closed' }),
    })
      }
  })
}

上述代码就可以用于处理IFTTT Marker所发送的GET请求,我们从query参数中取到文章标题之后再去搜索相对应的Issues,再通过GitHub API将其关闭。

而与此同时,我们在文章的阅读过程中,有时候也会想要对文章中的亮点部分进行高亮,甚至添加自己的一些想法和总结,那我们也可以用IFTTT Marker和Webtask的套路添加至GitHub Issues的comments当中。具体的详细代码就不贴了,更多内容都已经放在我的GitHub上:JimmyLv/demo.serverless-mern,与此同时我的阅读列表也公开在GitHub上:Issues · JimmyLv/reading,欢迎围观。


总结与后续计划

随着时间的推移,日常你只需要在Instapaper添加并阅读文章即可,而背后利用Serverless所搭建的整套阅读追踪系统将会任劳任怨的帮你记录下所有的踪迹和笔记,你只需要在特定的时候定期review、分析阅读的效果与预测效果,与此同时结合自己的时间统计系统,持续不断地改进自己的阅读目标与阅读计划。

最后再来考虑一下后续计划,比如说我现在只是简单把Instapaper中高亮部分和阅读笔记作为评论放到GitHub的comments里面,但是最终我需要把它收藏到自己的个人知识库即Diigo,这也是可以通过API自动实现的,以及最终需要被刻意记忆的部分还需要与Tinycards或者Quizlet API相集成,对抗艾宾浩斯遗忘曲线。

与此同时,还需要根据文章类型和难易程度具体划分一下估点,而不是现在简简单单的1点,比如说Instapaper也有根据字数来预测的阅读分钟数,以及根据中文或英文、技术或鸡汤等不同种类文章阅读难度进行区分,从而使整套追踪系统更具有效性与参考性。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-09-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 思特沃克 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Elasticsearch之利用bulk提高写入性能(含源码分析)
bulk是批量的意思,也就是把原来单个的操作打包好,通过批量的api提交到ES集群。下面是个示例:
用户7634691
2021/04/09
5.4K0
Elasticsearch之利用bulk提高写入性能(含源码分析)
Elasticsearch Document Index API详解、原理与示例
本节将开始介绍Document API,本节将重点介绍ElasticSearch Doucment Index API(新增索引)。
丁威
2019/06/10
3K0
Elasticsearch Document Index API详解、原理与示例
6 ElasticSearch 高级-应用篇
bulk 批量操作 :将文档 增删改查 一系列的操作,通过一次请求全部做完。优点:可以减少网络传输次数。
收心
2022/01/17
3820
6 ElasticSearch 高级-应用篇
StringBoot集成Elasticsearch
官方文档 此处 本文使用Elasticsearch版本为7.8.0 创建一个项目 勾选es依赖 编译版本一定是8以上 默认集成的版本 跟我们本地安装的版本不一样 自己指定跟自己es版本匹配即可 <properties> <java.version>1.8</java.version> <!--自己定义es版本--> <elasticsearch.version>7.8.0</elasticsearch.version> </prop
暴躁的程序猿
2022/03/23
4080
StringBoot集成Elasticsearch
ElasticSearch高版本API的使用姿势
ElasticSearch之前我没有深入去学过,在上家公司也是简单用了一下,本来是想用来做千万级ip库数据缓存的,后面查询耗时就弃用了,也就没有深入去学习。之前看过一些视频,也只是说说怎么去使用而已。
Bug开发工程师
2020/03/09
2.1K0
JavaRestClient操作Elasticsearch批量新增文档
导包 导包可以根据 文档 里导入依赖 这里就不写依赖了 批量新增文档 import com.google.gson.Gson; import com.leyou.pojo.Item; import org.apache.http.HttpHost; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.act
用户9006224
2022/12/21
5560
JavaRestClient操作Elasticsearch批量新增文档
Elasticsearch Multi Get、 Bulk API详解、原理与示例
从上面所知,mget及批量获取文档,通过add方法添加多个Item,每一个item代表一个文件获取请求,其相关字段已在get API中详细介绍,这里就不做过多详解。
丁威
2019/06/10
2.3K0
Elasticsearch Multi Get、 Bulk API详解、原理与示例
ElasticSearch 实用学习笔记 (从入门到精通)
找到 config 下的 kibana.yml 文件,修改最后一行为 i18n.locale: “zh-CN”
Gorit
2021/12/08
2.3K0
ElasticSearch 6.x 学习笔记:28.Java API之文档批量操作
https://www.elastic.co/guide/en/elasticsearch/client/java-api/6.1/java-docs-multi-get.html
程裕强
2022/05/06
4400
ElasticSearch 6.x 学习笔记:28.Java API之文档批量操作
Elasticsearch多文档操作
Elasticsearch除了可以文档Index操作外,也提供了一次可以操作多个文档Index的API,上一篇已经把单文档的说了,从今天起说一说多文档Index操作。多文档操作的API统称Multi-document APIs
BUG弄潮儿
2020/06/12
7670
Elasticsearch BulkProcessor 的具体实现
本文示例使用的是 Spring Boot 框架,由于该框架有默认的 Elasticsearch 版本,为了避免版本混乱或冲突,我在 pom.xml 文件内添加了如下依赖:
create17
2019/08/15
6.9K0
Elasticsearch BulkProcessor 的具体实现
ELK专栏之Java API操作-02
● ES技术比较特殊,不像其他分布式、大数据方便的技术,比如Hadoop、Spark和Habase等。ES代码层面很好写,难的是概念的理解。
大忽悠爱学习
2022/09/28
6400
ELK专栏之Java API操作-02
Elasticsearch Java API 索引的增删改查(二)
Index API 允许我们存储一个JSON格式的文档,使数据可以被搜索。文档通过index、type、id唯一确定。我们可以自己提供一个id,或者也使用Index API 为我们自动生成一个。
全科
2018/08/15
4K0
Java API 代码操作ElasticSearch7.6.1(2)
添加FastJSON依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.60</version> </dependency> 关于文档的操作,干货走不停,基本项目开发中的API都在下面 package com.dance.danceesapi.test; import com.alibaba.fastjson.JSON; import com
彼岸舞
2020/12/03
1K0
彻底搞懂 Elasticsearch Java API
在明确了ES的基本概念和使用方法后,我们来学习如何使用ES的Java API. 本文假设你已经对ES的基本概念已经有了一个比较全面的认识。
小勇DW3
2019/07/08
10K0
Elasticsearch应用之京东搜索
---- 京东搜索Elasticsearch 开发环境 elasticsearch 7.10.1 集成IDE idea elasticsearch-head maven 3.6.3 所有开发环境
后端码匠
2021/02/26
5470
Elasticsearch应用之京东搜索
Elasticsearch入门与实战
在电商等常见的搜索业务场景中,Elasticsearch扮演着举足轻重的作用。它对于数据的准实时搜索可以达到很高的查询效率,并且天生自带的分布式、高可用、易扩展的能力,也使其具有了十足的魅力。那么,下面就是本篇文章的大纲结构
爪哇缪斯
2023/05/10
1.2K0
Elasticsearch入门与实战
spingboot2 整合ES7.2
包括中文分词:https://www.jianshu.com/p/d2afc19cafbd
用户5927264
2020/07/21
5670
ES5.6 Bulk源码解析
Bulk注册 在启动类BootStrap的start()方法中,启动了node.start()方法。在Node初始化的过程中,加载了一系列的模块和插件,其中包含ActionModel。 ActionModule actionModule = new ActionModule(false, settings, clusterModule.getIndexNameExpressionResolver(), settingsModule.getIndexScopedSetting
YG
2018/05/23
9811
SpringBoot集成ES-7.8
程序员 NEO
2023/10/01
2810
SpringBoot集成ES-7.8
相关推荐
Elasticsearch之利用bulk提高写入性能(含源码分析)
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 阅读习惯和个人知识管理体系
  • 稍后阅读中永远读不完的痛点:缺乏追踪
  • 可视化Cumulative Flow Diagram
  • IFTTT与Serverless架构
  • 流程化:APIs即服务
  • 初始化Webtask项目
  • Webtask的上下文绑定
  • 使用GitHub Issue追踪阅读列表
    • IFTTT:添加Instapaper文章后自动创建GitHub Issue
    • 使用GitHub Webhook更新Issue的Milestone
  • 集成ZenHub API:阅读可视化
    • 更新Issue的估点和Release
  • 归档Instapaper文章后关闭GitHub Issue
  • 总结与后续计划
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文