Coder Social home page Coder Social logo

qianxi0410 / gossip Goto Github PK

View Code? Open in Web Editor NEW
61.0 61.0 7.0 19.12 MB

A serverless static blog engine based on GitHub Issue System.

Home Page: https://qianxi0410.github.io/gossip

License: MIT License

JavaScript 3.34% TypeScript 96.34% CSS 0.32%
blog-engine nextjs react serverless static-site-generator

gossip's Introduction

I just wondered how things were put together. - Claude Shannon

gossip's People

Contributors

dependabot[bot] avatar mergify[bot] avatar qianxi0410 avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gossip's Issues

2022年终总结

年末了,看见大家都在发年终总结,自己其实也想写一篇来着,但是下笔的时候实在是不知道如何描述今年所做的一些事情,感觉很多事情在没有结果的时候说出来就会变成笑话,也许2023年的时候会把今年所做的事情好好总结一下吧,今年是不太可能了。这篇无意义的文章就简单占个位置吧,至少代表2022我还活着。当然,也希望2023对我好一点吧

documentation

Should add documentation to tell others how to use this engine.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): update dependency @types/node to v18.18.3
  • chore(deps): update dependency @types/react-syntax-highlighter to v15.5.7
  • chore(deps): update dependency autoprefixer to v10.4.16
  • chore(deps): update dependency postcss to v8.4.31
  • chore(deps): update nextjs monorepo to v13.5.4 (eslint-config-next, next)
  • chore(deps): update react monorepo (@types/react, @types/react-dom)
  • chore(deps): update dependency tailwindcss to v3.3.3
  • fix(deps): update dependency octokit to v3.1.1
  • fix(deps): update dependency sakana-widget to v2.7.0

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci-and-cd.yml
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
  • peaceiris/actions-gh-pages v3
npm
package.json
  • next 13.5.3
  • next-themes ^0.2.1
  • octokit ^3.0.0
  • react 18.2.0
  • react-dom 18.2.0
  • react-markdown ^9.0.0
  • react-syntax-highlighter ^15.5.0
  • rehype-raw ^7.0.0
  • remark-gfm ^4.0.0
  • remark-github ^12.0.0
  • rss ^1.2.2
  • sakana-widget ^2.4.3
  • @qianxi0410/eslint-config ^5.3.0
  • @types/node 18.18.1
  • @types/react 18.2.24
  • @types/react-dom 18.2.8
  • @types/react-syntax-highlighter ^15.5.6
  • @types/rss ^0.0.30
  • autoprefixer ^10.4.13
  • eslint 8.39.0
  • eslint-config-next 13.5.3
  • postcss ^8.4.21
  • tailwindcss ^3.2.4
  • typescript 5.1.6

  • Check this box to trigger a request for Renovate to run again on this repository

Configurable

Comments, tags, and other things need to provide configurable options.

可扩展哈希

可扩展哈希 是一种动态散列方案,其中的目录和桶被用来散列数据。
对于静态哈希来说,可扩展哈希的优势在于,在扩容的时候,不需要重新散列所有的数据,只需要重新散列一部分数据即可

静态哈希不等于不能扩容,只是扩容的时候需要重新散列所有的数据,并且需要重新寻找一个散列函数。

可扩展 hash 的大致架构如下图所示:

可扩展hash架构

其中几个概念:

  • 目录(direcotory):用来存储桶指针的数组,其中目录的大小为 2^全局深度,全局深度初始为 1,每次扩容时,全局深度加 1,即目录大小翻倍。这里需要注意,目录中会有多个指针指向同一个桶。
  • 桶(bucket): 用来存储数据的数组,每个桶的大小固定,由参数进行指定,局部深度初始为 1,每次分裂时,该桶局部深度加 1。
  • 全局深度(global depth): 用来确定目录的大小,此外,全局深度还用来确定数据的散列地址。例如,全局深度为 1 时,数据的散列地址为 0 或 1,全局深度为 2 时,数据的散列地址为 00、01、10、11。
  • 局部深度(local depth):局部深度用来确定在桶溢出时候进行的操作:当局部深度小于全局深度时,进行桶的分裂,且桶的局部深度加 1;当局部深度等于全局深度时,进行目录的扩容和桶的分裂,且全局深度和局部深度都加 1。指向当前桶的指针的个数等于 2^(全局深度 - 局部深度)。
  • 桶分裂:当桶溢出时,将桶中的数据重新散列到旧的桶和新的桶中。例如桶 A 已满,且 A 的局部深度为 1,溢出时,创建桶 A*,局部深度为 2,且将桶 A 的深度也改为 2。然后将桶 A 中的数据重新散列到桶 A 和桶 A*中。 这里更好的说法是,将桶 A 的数据进行重新散列。且散列的数据只会落在桶 A 和桶 A*中,而不会落在其他桶中。
  • 目录扩容:当全局深度增加时候,需要对目录进行扩容,即将目录的大小翻倍。且将新增加的目录的桶指针指向合适的桶。例如,当全局深度从 1 增加到 2 时,需要将目录的大小从 2 增加到 4,且将目录的第 2 个和第 3 个指针指向对应的桶 0 和桶 1。对应关系为: 遍历前一半目录索引,将其最高位从 0 变为 1 即可。公式为 dir[reverse_the_highest_bit(index)] = dir[index]

流程

流程如下所示:

流程

找到对应的桶之后,可以进行查找/删除/增加等操作。

举个例子:

此时的状态为:全局深度 1,局部深度 1,key 为"qianxi", hash(key) = 114514。

按照流程,先对 key = qianxi 应用 hash 函数,得到 114514。然后,寻找对应的目录索引 dir_index = (114514 & ((1 << 全局深度) - 1)) = 0,得到索引 0,在按照目录中所存放的桶指针找到的目录项 0 所指向的桶,随后进行对应的操作。

举个栗子

查找和删除操作这里都不讲,着重讲讲插入操作。

预设:桶的大小为 2,hash(key) = key,待插入的 key 为 1-8。

首先的初始情况为:

初始情况

  1. 插入 1,hash(1) = 1,dir_index = 1 & 1 = 1,所以插入到桶 1 中。
  2. 插入 2,hash(2) = 10,dir_index = 10 & 1 = 0,所以插入到桶 0 中。
  3. 插入 3,hash(3) = 11,dir_index = 11 & 1 = 1,所以插入到桶 1 中。
  4. 插入 4,hash(4) = 100,dir_index = 100 & 1 = 0,所以插入到桶 0 中。

此时,桶 0 和桶 1 都已满,状态如下:

阶段1

  1. 插入 5,hash(5) = 101,dir_index = 101 & 1 = 1,所以插入到桶 1 中。

问题来了,桶 1 已经满了(桶的大小固定且在这里设定为 2),而且此时桶 1 的局部深度为 1,全局深度也为 1,这就代表着,没有多余的指针指向桶 1,所以你需要首先对目录进行扩容,扩容后的目录如下:

第一次扩容

注意到,此时的全局深度增加 1 之后为 2,而且,扩容增加之后的目录指向了桶 0 和桶 1。且此时,全局深度为 2,局部深度为 1,key 为 5,hash(key) = 5, 插入到桶 1 中。

扩容之后,桶 1 的局部深度 1 小于全局深度 2,这就意味着,有不止一个指针指向桶 1,所以,你仅仅需要对桶 1 进行分裂。首先,需要找到另一个指向桶 1 的目录项,这里就是目录项 3,将其指向一个新的空桶,然后,对目录项 1 所指向的桶进行分裂(别忘了加上新增的元素 5),即对 1、3、5 这些元素重新进行哈希:

  • 插入 1,hash(1) = 1, dir_index = 1 & 11 = 1,所以插入到桶 01 中。
  • 插入 3,hash(3) = 11, dir_index = 11 & 11 = 11 ,所以插入到桶 11 中。
  • 插入 5,hash(5) = 101, dir_index = 101 & 11 = 01 ,所以插入到桶 01 中。

这样,就完成了桶的分裂,且没有桶溢出。

但是还个问题是?如何找到桶 1 的对分裂项桶 3 呢?假设桶 1 对应的分裂桶为桶 1*。
思路是,此时桶 1 的本地深度为 1,设桶 1 的索引号为 index,则桶 1*的目录索引号 index* = (1 << local_depth) | index,代入数据可以得到 index* = (1 << 1) | 1 = 3 = 11,所以桶 1* 对应的目录项为 3(11)。

分裂之后的状态如下:

分裂之后的状态

别忘了对新的桶和分裂的桶进行局部深度的更新。

  1. 插入 6,hash(6) = 110,dir_index = 110 & 11 = 10,所以插入到桶 10 中。

注意,此时,桶 10 的局部深度为 1,全局深度为 2,所以,此时只需要进行桶分裂,不需要对目录进行扩容。

所以步骤如上,对 2、4、6 进行重新哈希:

  • 插入 2,hash(2) = 10,dir_index = 10 & 11 = 10,所以插入到桶 10 中。
  • 插入 4,hash(4) = 100,dir_index = 100 & 11 = 00,所以插入到桶 00 中。
  • 插入 6,hash(6) = 110,dir_index = 110 & 11 = 10,所以插入到桶 10 中。

插入完成,且更新对应的局部深度之后的状态如下:

第二次分裂

  1. 插入 7,hash(7) = 111,dir_index = 111 & 11 = 11,所以插入到桶 11 中。
  2. 插入 8,hash(8) = 1000,dir_index = 1000 & 11 = 00,所以插入到桶 00 中。

全部插入完成之后的状态如下:

全部插入完成之后的状态

总结

所以,动态哈希的插入过程可以总结为:

  1. 计算哈希值,得到目录项的索引号,从而找到对应的桶。
  2. 如果目标桶可以直接插入,则直接插入。
  3. 如果不能直接插入,如果此时桶的局部深度等于全局深度则进行4,否则 5。
  4. 对目录进行扩容,然后将新增的目录项的桶指针指向对应的桶。
  5. 对目标桶进行分裂,将该桶中的所有数据和代插入的新数据进行重新哈希,然后插入到对应的桶中。
  6. 如果全部重新哈希之后插入成功,则完成插入,否则重复 2-5。

Semantic URL

The url of the article is now displayed with the issue number, and it is expected to be replaced with a semantic url in the future.

docker-proxy

最近在使用 docker 的时候,即便是配置了国内的镜像,也还是慢的可怕。
而且国内的镜像源并不能实时同步镜像的最新版本,所以还是选择了国外的源 + 代理的方式。

pull-time proxy

拉取镜像的时候,是使用dockerd守护进程。因此代理需要配置在dockerd环境,而这个环境是systemd负责,因此实际上是配置systemd代理。

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo touch /etc/systemd/system/docker.service.d/proxy.conf

添加下面的内容到proxy.conf文件中:

[Service]
Environment="HTTP_PROXY=http://ip:port/"
Environment="HTTPS_PROXY=http://ip:port/"
Environment="NO_PROXY=localhost,127.0.0.1"

这里的 ip 是你的代理 ip 一般是 localhost,port 则是你代理转发的端口。

run-time proxy

运行容器的时候,如果你需要在容器内使用代理,则需要配置容器的代理。

这里有三种配置方法:

  1. 容器运行时指定
docker run -e HTTP_PROXY=http://ip:port/ -e HTTPS_PROXY=http://ip:port/ -e NO_PROXY=localhost ...

这种方式的优点就是直接,但缺点就是每次启动容器都需要显示的设置。
为了解决这种情况,在 Docker 17.07 以上,可以使用配置 Docker 客户端的方式,即 2。

  1. 客户端全局配置

~/.docker/config.json中,加入以下内容:

{
  "proxies": {
    "default": {
      "httpProxy": "http://ip:port",
      "httpsProxy": "http://ip:port",
      "noProxy": "localhost,127.0.0.0/8"
    }
  }
}
  1. host 网络模式

如果你的容器使用的是 host 网络模式,那么容器内的网络就是宿主机的网络,因此可以直接使用宿主机的代理。

docker run --network host ...

上面的 ip 是 docker0 网卡的 ip,而不是容器内部的 ip。使用 ip addr show docker0 查看。

build-time proxy

容器构建的时候,本质上也是启动了一个容器。

这里没找到配置文件的方法,只能使用环境变量的方式,但是参数略有不同。

docker build \
    --build-arg "HTTP_PROXY=http://ip:port/" \
    --build-arg "HTTPS_PROXY=http://ip:port/" \
    --build-arg "NO_PROXY=localhost,127.0.0.1" \
    ...

同样的,这里的 ip 也是docker0网卡的 ip。

构建过程中,更推荐使用 host 网络模式,因为这样可以直接使用宿主机的代理。

重启生效

重启计算机即可

build-time 代理是在执行前设置的,所以修改后,下次执行立即生效。run-time 代理的修改也是立即生效的,但是只针对以后启动的容器,对已经启动的容器无效。

pull-time代理的修改比较特殊,它实际上是改systemd的配置,因此需要重载systemd并重启dockerd才能生效。

sudo systemctl daemon-reload
sudo systemctl restart docker

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Location: renovate.json
Error type: Invalid JSON (parsing failed)
Message: Syntax error near // {
//

终端工具集

俗话说,工欲善其事,必先利其器。差生文具多罢了!

推荐一些能够提升效率的终端工具:

yay: 又一个 aur helper,为什么不推荐paru,因为yay看起来更开心一些。

zsh: 比bash更强的 shell。

oh-my-zsh: 一个zsh的框架,自带许多插件和主题。

starship: zsh的主题,但是更好看,而且更快。

kitty: 一个 GPU 加速的终端,虽然的 python 写的,不用alacritty是因为它不支持连写。

FiraCode: 一个带连写的编程字体。

git: 版本管理。

hub: 一个更好的git增强工具。

cli: GitHub 官方的命令行工具,可以省去一些图形化操作。和hub有些功能重合。

lazygit: 终端的git命令 UI。

lazydocker: 终端的docker命令 UI。

degit: 简单的git项目脚手架,能够清除仓库的提交历史。

difftastic: git diff命令的增强。

ni: 包管理工具卷上天,ni大一统。

pnpm : 更快、更快、还是他妈的更快。

npm-check-updates: package.json的依赖更新工具。

zoxide: autojump,但是是用rust写的。

ranger: 一个终端的文件管理器。

fzf: 模糊查询。

fzf-tab: 用 fzf 替换 zsh 的默认补全选择菜单。

mcfly: 更加友善的zsh历史命令搜索提示。

neovim: vim fork 出来的终端编辑器,但是更 powerful

gvm: go 多版本管理工具。

fnm: node多版本管理工具。

tmux: 让你的session和终端分离。

htop: 更好的top命令。

exa: 更好的ls命令。

duf: 更好的df命令。

ncdu: 更好的du命令。

tldr: 太长不看。

bottom: 系统的各种运行时参数查看。

neofetch: 系统参数查看。

scc: 项目代码行数查看。

httpie: 或许是更好的curl

ripgrep: 安息吧,grep。更好的正则查询过滤。

golines: 限制你的go代码单行最大长度。

gofumpt: 更好的gofmt,完全和前者兼容。

golangci-lint: go的 lint 工具。

eslint: 让你的js代码更加规范。

vite: f**k webpack

tig: 更好的git log查看器。

gping: 带有可视化界面的ping

bat: 更好的cat

act: 在本地运行你的GitHub Action。

procs: 更好的ps

sd: 直观的查找和替换 CLI,更好的sed

RSS support

Should add RSS support for this blog engine.

使用null-ls来统一neovim的格式化方案

巨硬家编辑器vscode在打开大型项目时,无论启动速度还是补全速度都非常地拉胯,因此还是决定将主力编辑器切换为neovim,配置好后,搭配上tmux,在终端下的体验非常的丝滑。

这里我并没有从 0 开始进行配置,GitHub 上有很多不错的现成解决方案,这里我直接使用了nvimdots方案。该方案使用efm通用语言服务器作为格式化的解决方案,但是我觉得efm的配置还是太过零散,像gorust都在自己官方内置的 LS 中自带了格式化工具,而jsonsh等不自带的就需要交给efm来进行格式化,这样其实显得割裂,而操作起来还是比较繁琐,配置和修改都比较麻烦。

相比于efm, 这里我比较推荐的是null-ls,作为一个和efm功能相似的替代品,它支持更加统一的配置方案,无论是gorust,还是jsonsh等。它支持大部分主流语言的格式化方案,基本只需要进行很少的配置。所以,现在我的neovim格式化方案都统一交给null-ls来解决,不再考虑各种语言官方的 LS 是否自带格式化工具。此外,另一个比较吸引我的是,它可以轻松的配置多个格式化工具对文件进行链式格式化。对于go这种需要多个格式化工具的语言来说,在使用null-ls的方案下,可以轻松实现gofumpt -> goimports -> golines的链式格式化方案,不用手敲命令行,体验还是非常地不错。

CI has some problems

CI should only be triggered when the repository holder pushes and when an issue with a specific label is submitted.

style adjustment

The current style is still a bit fancy and needs to be adjusted.

Article Sidebar Navigation

Need to add article sidebar navigation to reduce anxiety for users. Again, this should also be configurable.

Add article tag support

The GitHub issue naturally provides a tag system, so it should also support the tag system here.
We should be able to find all the articles under that tag by tag.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.