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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Clawflake</title>
<meta name="author" content="Nicolas Paul" />
<meta name="description" content="A generation system with time-sortable keys." />
<meta name="keywords" content="clawflake,discord,twitter,id,generator,specification,distributed" />
<meta name="referrer" content="origin" />
<meta name="theme-color" content="#dc8400" />
<meta name="color-scheme" content="light dark" />
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0,user-scalable=yes" />
<meta name="creator" content="Nicolas Paul" />
<meta name="googlebot" content="all" />
<meta name="publisher" content="Nicolas Paul" />
<meta name="robots" content="all" />
<link rel="sitemap" href="/sitemap.xml" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@ncs_pl" />
<meta name="twitter:creator" content="@ncs_pl" />
<meta name="twitter:title" content="Clawflake" />
<meta name="twitter:description" content="A generation system with time-sortable keys." />
<meta property="og:title" content="Clawflake" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://staticgovanityurls.nicolaspl.com/" />
<meta property="og:description" content="A generation system with time-sortable keys." />
<meta property="og:determiner" content="" />
<meta property="og:locale" content="en" />
<meta property="og:site_name" content="Nicolas Paul" />
<link rel="stylesheet" href="https://fashion-pepper.nicolaspl.com/css/fashion-pepper.css">
<link rel="stylesheet" href="css/prism.css">
<link rel="stylesheet" href="css/style.css">
<script src="js/prism.js"></script>
</head>
<body>
<header>
<nav>
<ul>
<li><strong>Clawflake</strong></li>
<li><a href="/">Home</a></li>
<li><a href="#license">License</a></li>
</ul>
</nav>
</header>
<main>
<h1 id="clawflake">Clawflake</h1>
<p>Clawflake is a distributed ID number generation system inspired from
<a href="https://github.com/twitter-archive/snowflake/tree/snowflake-2010">
Twitter's Snowflake</a>.
</p>
<p> The goal of Clawflake is to be hosted as a distributed system with
all workers being isolated from each others apart from the machine ID.
</p>
<h2 id="format">Format</h2>
<p>
Unlike Snowflake, the composition of a Clawflake uses all 64 bits.
</p>
<table>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Bits</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td><code>time</code></td>
<td><code>45</code></td>
<td><code>The number of milliseconds passed from a configured epoch.</code></td>
</tr>
<tr>
<th scope="row">2</th>
<td><code>sequence</code></td>
<td><code>12</code></td>
<td><code>A sequence number rolling out whenever required.</code></td>
</tr>
<tr>
<th scope="row">3</th>
<td><code>machine</code></td>
<td><code>7</code></td>
<td><code>An identifier for the worker, between 0 and 127.</code></td>
</tr>
</tbody>
</table>
<p>
Therefore, Clawflake ID numbers gives <mark>2<sup>45</sup> - 1 = 1115.7</mark> years
of safety from the configured epoch.
Thanks to the sequence number, a worker can handle <mark>2<sup>12</sup> = 4069</mark>
generations per milliseconds at peak.
The system can accept a maximum of <mark>2<sup>7</sup> = 128</mark> machines for a
given epoch.
</p>
<cite>
Since Clawflake uses the most significant bit, converting a Clawflake ID
from <i>uint64</i> to <i>int64</i> is not safe.
</cite>
<h2>Usage</h2>
<p>
Before launching any worker, you need to determine the following
information:
<ul>
<li><i>epoch</i>: corresponds to the epoch workers will be using to
generate IDs.</li>
<li><i>machine</i>: the identifier for the machine.</li>
</ul>
</p>
<p>
Due to the format of a Clawflake, you can only have 128 workers (machine IDs
between 0 and 127).
</p>
<p>
You can compile the worker by running the following command:
</p>
<pre><code lang="language-bash">
make generator
</code></pre>
</p>
This will generate an executable named <code>generator</code> inside the
<code>bin</code> directory.
</p>
<p>
You can then start the worker by running:
<pre><code class="language-bash">
export MACHINE_ID= # Worker ID, between 0 and 127
export EPOCH= # Epoch to use in ID generation
./bin/generator -machine_id=$MACHINE_ID -epoch=$EPOCH -grpc_host=":5000"
</code></pre>
</p>
<p>
<strong>TIP:</strong> Use the flag <code>-help</code> to view the
documentation for the flags.
</p>
<p>
A worker should be running on port <code>5000</code>. You can try generating some
Clawflake ID numbers using the
<a
href="https://github.com/n1c00o/clawflake/blob/master/api/nicolaspl/clawflake/generator/v3/generator.proto">
Generator API
</a>.
</p>
<p>A test client is available in <a
href="https://github.com/n1c00o/clawflake/blob/master/cmd/testclient/main.go">cmd/testclient/main.go</a>.
</p>
<h2 id="license">License</h2>
<p>
Clawflake is governed by a BSD-style license that can be found in the
<a href="https://github.com/n1c00o/clawflake/blob/master/LICENSE"><code>LICENSE</code></a> file.
</p>
<p>
The older codebase was licensed by the Apache License, Version 2.0, however
none of the old code still exists.
</p>
</main>
<footer>
<hr />
<ul>
<li><a href="/">Website</a></li>
<li><a href="https://github.com/n1c00o/clawflake" target="_blank">Source</a></li>
<li><a href="https://nicolaspl.com" target="_blank">Nicolas Paul</a></li>
</ul>
<p>© 2023</p>
</footer>
</body>
</html>
|