2019

2019/07/29

01 简单了解 netlify 的一些配置

由于所有的静态资源都打了 hash,为所有静态资源添加了永久缓存。另外配置了自动部署

[[headers]]
  for = "/assets/*"

  [headers.values]
    cache-control = "max-age=31536000"

配置文件

02 一篇关于 exit code 与 node 中异常的文章

https://shanyue.tech/post/exit-code-node-and-docker.html

2019/07/30

01 一篇关于调试 js 的示例总结

https://shanyue.tech/post/js-debug-examples/

02 关于 kill 的一些信号 (signal)

当起了一个 server 时,

  • <Ctrl+C> 使用 SIGINT(2) 来杀死进程
  • kill 默认使用 SIGTERM(15) 杀死进程,进程可以对该信号进行捕捉
  • kill -9 使用 SIGKILL(9) 杀死进程,进程无法对信号进行捕捉 (强制杀死)

03 对指定进程的 signal 进行监控

strace -e signal -p $pid

2019/07/31

01 graphql 中 apollo-server 对 cache 的处理

今天对我的脚手架的服务端添加了对缓存的处理,具体改动如下

https://github.com/shfshanyue/apollo-server-starter/commit/e40f59640f472146a4e9f1c94832ca431a0dbb11

具体看了下相关插件关于缓存的源码,发现与我想的缓存机制不大一样。graphql 可以说是以 field 为主要关注点,本以为它会根据 field 来进行缓存,就如同客户端的apollo-clientrelay 一般。结果它还是以整个 query 为单位进行缓存,不过,细想也是有原因的:

  1. 方便 http response,(GET)
  2. 返回 field 的数据无法组成 resolver 函数中 Parent 的数据类型

关于如何对一个 query 计算它的缓存时间的源码如下

type Post @cacheControl(maxAge: 240) {
  id: Int!
  votes: Int @cacheControl(maxAge: 300)
}

type Query {
  latestPost: Post @cacheControl(maxAge: 10)
}

02 对个人 Next + React + GraphQL 的项目添加了简单的 ts 支持

以下是具体改动,Next 现在对新增 ts 支持的体验真是棒,只需要按着提示走就可以了

2019/08/01

每日一诗:荷风送香气,竹露滴清响。

01 React Hook 的学习

hook 的出现真是振奋人心,可惜现在才看。最喜欢它的两点:复用逻辑和减少嵌套。

graphql 中再配合 react-apollon-hooks 使用,体验极佳。

PS: 再结合 graphql-code-generator 前端自动生成类型/(及注释文档),不知少了多少前后端的沟通。graphql 后端的接口一出来,前端立即可以

  1. 使用 graphql-code-generator 自动拉取 type.ts,解决前后端联调最大的问题,及 API 的前后端数据类型一致性,且不用手工维护
  2. 在 type.ts 中有注释,即文档,不懂的可以再问后端
  3. 自动补全以及类型校验接口字段

02 总结了一份关于 graphql-code-generator 自我感觉良好的配置文件

overwrite: true
schema: "http://localhost:5000/graphql"
documents: "query.gql"
generates:
  query.ts:
    plugins:
      - "typescript"
      - "typescript-operations"
    config:
      scalars:
        DateTime: Date
        JSON: "{ [key: string]: any }"
      namingConvention:
        typeNames: change-case#pascalCase
        transformUnderscore: true
        enumValues: keep

2019/08/02

因过竹院逢僧话,又得浮生半日闲。

01 看源码 Bluebird.map 中的 concurrency 的实现原理 (doing)

自然自己可以实现一个关于 Promise 的限流,但是能设计好 API 就是另一回事了

function get (i) {
  console.log('In ', i)
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve() 
      console.log('Out', i)
    }, i * 1000)
  })
}

// 如何使用 get 请求这些数据,并且限流三个
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let count = 0
function run () {
  if (count < 3 && list.length) {
    count+=1
    get(list.shift()).then(() => {
      count-=1 
      run()
    })
  }
}

run()
run()
run()

2019/08/03

叶上初阳干宿雨,水面清圆,一一风荷举。

01 看源码 featurist/promise-limit 中的 promise 限流的实现

02 接昨日,实现一个 Promise.map

class Limit {
  constructor (n) {
    this.limit = n
    this.count = 0
    this.queue = []
  }

  enqueue (fn) {
    return new Promise((resolve, reject) => {
      this.queue.push({ fn, resolve, reject })
    })
  }

  dequeue () {
    if (this.count < this.limit && this.queue.length) {
      const { fn, resolve, reject } = this.queue.shift()
      this.run(fn).then(resolve).catch(reject)
    }
  }

  async run (fn) {
    this.count++
    const value = await fn()
    this.count--
    this.dequeue()
    return value
  }

  build (fn) {
    if (this.count < this.limit) {
      return this.run(fn)
    } else {
      return this.enqueue(fn)
    }
  }
}

PromiseMap = function (list, fn, { concurrency }) {
  const limit = new Limit(concurrency)
  return Promise.all(list.map((...args) => {
    return limit.build(() => fn(...args))
  }))
}

function get (i) {
  console.log('In ', i)
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve() 
      console.log('Out', i)
    }, i * 1000)
  })
}
PromiseMap(list, i => get(i), { concurrency: 3 })

2019/08/04

风吹古木晴天雨,月照平沙夏夜霜。

2019/08/05

黑云翻墨未遮山,白雨跳珠乱入船

01 总结了两篇关于 promise 的文章

2019/08/06

居高声自远,非是藉秋风

01 解决 typescript/webpack 环境中 import query.gql 的问题

https://github.com/shfshanyue/shici/commit/fc59b3600c52fa106b224a2215734903fb58bd69

02 看源码 graphql-tag

03 了解 node 中的 stream 以及原理

2019/08/07

惊鹊栖未定,飞萤捲帘入。

01 思考两个问题

02 关于 prerender 与 ssr 的取舍思考

03 大致了解 musl

2019/08/08

睡起秋声无觅处,满阶梧叶月明中。

2019/08/09

01 看 graphql.js 的源码

02 graphql.js 中有一段 Promise.reduce 的实现,用来串行 Promise。比较简单,贴下边

export default function promiseReduce<T, U>(
  values: $ReadOnlyArray<T>,
  callback: (U, T) => PromiseOrValue<U>,
  initialValue: PromiseOrValue<U>,
): PromiseOrValue<U> {
  return values.reduce(
    (previous, value) =>
      isPromise(previous)
        ? previous.then(resolved => callback(resolved, value))
        : callback(previous, value),
    initialValue,
  );
}

2019/08/10

01 看 dataloader 源码

关于 Promise 各种功能实现的一个万能的队列...

new Promise((resolve, reject) => {
  queue.push({
    fn,
    resolve,
    reject
  })
})

02 看 CMAKE 用法

2019/08/11

月华收,云淡霜天曙。

01 体验 taro,使用它做一个小程序

02 使用 react-hook 写一个倒计时

恩,这可以考察关于 react hook 的了解与熟悉程度。

刚开始熟悉 react-hook 时,写一个倒计时组件还是比较有点难度的

这一条加入我的候选人面试套餐

03 react-hook 中的 useEffect 的执行时机

2019/08/12

01 htop/ps 中的 time

time 指 cpu user time + cpu system time. etime 指启动了多久时间

2019/08/13

紫薇朱槿花残,残阳却照阑干

01 了解数据仓库以及分层

  • ODS: Operational Data Store
  • DW: data warehouse
    • DWD
    • DWB
    • DWS
  • DIM: 维度数据层

就我理解,数据仓库分层,就如同业务代码上线前的若干环境

02 了解 postgres 的 Query Plan

添加索引后,要确保是否有效,可以先 explain 一下

03 了解 postgres 的 search path

show search_path

恩,还有特殊的 schema:pg_catalog,自带 search_path...

2019/08/15

寒蝉凄切,对长亭晚,骤雨初歇。

2019/08/16

陇首云飞,江边日晚,烟波满目凭阑久。

01 linux jobs

需要注意的是,jobstty 相关联。

$ npm run dev

# 放到后台并停止该程序 
$ <Ctrl+Z>

# 激活该程序
$ bg

# 放到前台
$ fg

不过一般情况下还是用 tmux 使用多,特殊情况下,如在 vscode 的终端会使用 jobs

02 一篇文章 如何为测试环境添加假数据

03 stty size

stty size 输出当前 tty 的高和长。虽然我以前是通过 seq 1 100 来看控制台的高...

2019/08/17

登孤垒荒凉,危亭旷望,静临烟渚。

01 postgres 把查询结果写到文件中

\o /tmp/query.txt
select * from users limit 100
\o

02 What is RSS and VSZ in Linux memory management

一般我理解 RSS 为物理内存,VSZ 理解为虚拟内存,而在监控线上系统时,也是看 RSS。这篇文章说的更细一些

  • RSS
  • VSZ
  • PSS

03 统计诗词中的前五百个高频字

select array_to_string(array(select char from char_cloud GROUP BY char ORDER BY sum(count) desc limit 500), '')

04 start transaction 与 begin 的区别

好像没啥区别...

2019/08/18

欲买桂花同载酒,终不似,少年游。

2019/08/19

千里澄江似练,翠峰如簇。

01 UTM

关于打点的一些数据,用以了解广告投放的效果。自从转入了 toC 这边,越来越多地接触了运营的东西

  • utm_source:标识为您的媒体资源带来流量的广告客户、网站、出版物等,例如:google、newsletter4、billboard。
  • utm_medium:广告媒介或营销媒介,例如:每次点击费用、横幅广告和电子邮件简报。
  • utm_campaign:产品的具体广告系列名称、标语、促销代码等。
  • utm_term:标识付费搜索关键字。如果您采用人工方式标记付费关键字广告系列,那么您还应使用 utm_term 来指定相应关键字。
  • utm_content:用于区分相似内容或同一广告内的链接。例如,如果您在同一封电子邮件中使用了两个号召性用语链接,就可以使用 utm_content 并为每个链接设置不同的值,以便判断哪个版本的效果更好。

02 补了两篇半年前的旧文

2019/08/20

无奈夜长人不寐,数声和月到帘栊。

01 SQL 中的隔离级,悲观锁与 MVCC

补一篇文章: 关于统计诗词字云的解决方案

2019/08/21

草色新雨中,松声晚窗里。

Last Updated: 8/21/2019, 12:05:59 PM