0%

从tun读出来后再写入tun,下次读还会将自己刚写入的packet读出来,如果设置默认路由是tun网卡,会导致死循环。下文会介绍解决routing loop的多种方法

https://www.kernel.org/doc/Documentation/networking/tuntap.txt

How does Virtual network device actually work ?
Virtual network device can be viewed as a simple Point-to-Point or
Ethernet device, which instead of receiving packets from a physical
media, receives them from user space program and instead of sending
packets via physical media sends them to the user space program.

Let’s say that you configured IPv6 on the tap0, then whenever
the kernel sends an IPv6 packet to tap0, it is passed to the application
(VTun for example). The application encrypts, compresses and sends it to
the other side over TCP or UDP. The application on the other side decompresses
and decrypts the data received and writes the packet to the TAP device,
the kernel handles the packet like it came from real physical device.

一共两个方法, read 和 write

read from tun读取数据包

阅读全文 »

生命周期的抽象

将LT想象成scope不太容易理解,可以将其想象成链。标注同一个的引用必须共存亡。通过 'a, 多个引用链在一起。
![将引用比作绳子]](https://user-images.githubusercontent.com/24750337/114650520-fb8a8c80-9d14-11eb-93a0-3ee191ff4938.png)

https://doc.rust-lang.org/stable/book/ch10-03-lifetime-syntax.html
https://www.zhihu.com/question/30861652/answer/132841992

为什么生命周期被如此设计

跨函数的变量生存期分析及其复杂,要分析完成各种条件语句,且需要的值只有在运行时才能确认,这就加大了编译器分析的复杂度(又可认为不可能进行分析),Rust通过在函数,结构体上进行生命周期标注,将分析的范围限定到函数内部,从而完成整个分析的过程。这就是为何生命之后需要在 函数, 结构体 上进行 'a 标注

阅读全文 »

我对Pin 的整体理解 - 为了解决unsafe场景下move问题

提出的必要性 - 不依赖Pin能否做到希望的 不被move ?

Pin的作用是防止move,但如果程序员小心处理,那就不会出错。为什么还需要Pin呢?

既然在某些场景下move是错的,那作为安全的编程语言,就需要显式限制这些场景。不能将安全交给人的直觉保证,这是Rust编译器的责任,不是人的

反面例子是C++,程序员犯错的时候还少吗?

阅读全文 »

Rust 基本语法学习

为什么会有此文

目标是给 Deno 项目贡献代码,结果发现我还不会 Rust …,所以要先啃 Rust

我发现 rust,ruby 和掌握的 C 系风格语言很不同。

我从 C# 转 Java 时根本没花时间『特地』学习语法,因为他们两个太像了,直接找了一份开源代码对着抄,边抄边查文档就会了。

阅读全文 »

比如我们有个表(UserLiked)记录用户喜欢的 workspace 内容,且一个用户可以喜欢多个 workspace

前端的 UI 展现是用户点击 like 界面显示出用户全部喜欢的 workspace

现在有下面两种表结构,你觉着哪种不错?

注意,MYSQL并不支持Array类型,这里只是比较表设计。

Mongodb支持Array,文档数据库表结构灵活,不要滥用Array,不要过早优化

阅读全文 »

实现一个功能,根据第一个字段输入的值来动态更改其余字段的类型

比如如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface InputProps {
label: string;
}
interface SelectProps {
name: string;
}
export interface InputType {
input: InputProps;
select: SelectProps;
}
export type FormItemDefinition = {
type: 'input' | 'select';
componentProps?: any
}
阅读全文 »

UseMemo 的使用

FP 组件每次更新渲染都会被调用,我们希望更新时保存上次渲染的状态
比如如下组件 onChange触发之后组件更新,结果输入的值又没了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const [formData, setFormData] = useState("");
const [formSchema, setFormSchema] = useState(defaultSchema);
return (
<Row>
<Col span={8}>
<div className="pattern-editor">
<Editor
initialCode={JSON.stringify(defaultSchema)}
onChange={() => {}}
></Editor>
</div>
</Col>
<Col span={8}>
<div className="WYSIWYG-editor">
<SchemaForm
schema={formSchema}
onChange={(e) => {
setFormData(JSON.stringify(e.formData));
}}
>
<React.Fragment></React.Fragment>
</SchemaForm>
</div>
</Col>
<Col span={8}>
<div className="config-output">
<Editor
initialCode={JSON.stringify(formData)}
onChange={() => {}}
></Editor>
</div>
</Col>
</Row>
);

而使用useMemo改造后,只要依赖数组不变化,那组件不会被重新渲染,状态还会被保留

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
const [formData, setFormData] = useState("");
const [formSchema, setFormSchema] = useState(defaultSchema);
return (
<Row>
<Col span={8}>
<div className="pattern-editor">
<Editor
initialCode={JSON.stringify(defaultSchema)}
onChange={() => {}}
></Editor>
</div>
</Col>
<Col span={8}>
<div className="WYSIWYG-editor">
{useMemo(
() => (
<SchemaForm
schema={formSchema}
onChange={(e) => {
setFormData(JSON.stringify(e.formData));
}}
>
<React.Fragment></React.Fragment>
</SchemaForm>
),
[formSchema]
)}
</div>
</Col>
<Col span={8}>
<div className="config-output">
{useMemo(
() => (
<Editor
initialCode={JSON.stringify(formData)}
onChange={() => {}}
></Editor>
),
[formData]
)}
</div>
</Col>
</Row>
);
阅读全文 »

我们明明可以在async之后直接调用dispatch,为什么又要多此一举引入中间件呢?

为什么需要中间件来处理Redux异步数据流?

如果异步之后直接Dispatch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// action creator
function loadData(dispatch, userId) { // needs to dispatch, so it is first argument
return fetch(`http://data.com/${userId}`)
.then(res => res.json())f
.then(
data => dispatch({ type: 'LOAD_DATA_SUCCESS', data }),
err => dispatch({ type: 'LOAD_DATA_FAILURE', err })
);
}

// component
componentWillMount() {
loadData(this.props.dispatch, this.props.userId); // don't forget to pass dispatch
}

如果使用 react-thunk

阅读全文 »

本文转载自 http://jiangew.me/actor-model/

Actor 模型背景

Actor 模型(Actor model)首先是由Carl Hewitt在1973定义, 由Erlang OTP(Open Telecom Platform)推广,其消息传递更加符合面向对象的原始意图。Actors属于并发组件模型,通过组件方式定义并发编程范式的高级阶段,避免使用者直接接触多线程并发或线程池等基础概念。

流行语言并发是基于多线程之间的共享内存,使用同步方法防止写争夺,Actors使用消息模型,每个Actors在同一时间处理最多一个消息,可以发送消息给其他Actors,保证了单独写原则。从而巧妙避免了多线程写争夺。

阅读全文 »