forked from amphp/amphp.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
153 lines (120 loc) · 5.06 KB
/
index.html
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
---
layout: landing
title: Welcome to asynchronous multitasking PHP
description: Amp is a non-blocking concurrency framework for PHP applications.
---
<div class="landing">
<header class="article-header">
<h1>{{page.title}}</h1>
</header>
<p>
Amp is a non-blocking concurrency framework for PHP applications.
</p>
<h2 id="non-blocking-io">What is asynchronous non-blocking I/O?</h2>
<p>
Usually, at least in the PHP world, everything happens synchronously in your code. When you make a
database query, you call a function. That function sends the query to the server, then it waits (or
"blocks") until it gets a response and returns the retrieved value.
</p>
<p>
We can do better than that. With non-blocking I/O we can perform other tasks while waiting for the
database server to return a result. We could fire off a second query in the meantime or perform any
other task.
</p>
<p>
You might respond "What's so bad about waiting? The kernel will just schedule other tasks during that
waiting time?" While that is true, and it's how most applications work today, it's not the end of the
story.
</p>
<p>
Let's make a comparison with cooking a soup. With blocking I/O, you first have to peel the
potatos and other vegetables and then slice them (CPU work). Once you're finished, you can turn on the
stove. Now you're waiting for the water in the pot to become hot. It's hot now, so you can put all
vegetables into the pot and wait for it to be done.
</p>
<p>
With non-blocking I/O, you could have turned on your stove directly. You could delegate the actual hard
work of slicing the vegetables to workers (your children). While being in idle waiting for the stove
and the workers, you could stream a video from YouTube and watch it. Once everything is ready, you can
put it into the pot. While you're waiting for it to be done, you can play a game with your children.
</p>
<p>
But how does it work in reality? All I/O is managed by the kernel. We just write to the kernel's buffer,
we don't wait until the data is actually sent to the other side. In the mean time, we can do other
things. Once we have an answer, the kernel will notify us that there's a new readable event.
</p>
<p>
This waiting time isn't limited to databases, it's more and more important as you add I/O to your
application, e.g. by using microservices. Non-blocking I/O makes more efficient use of your processes,
because you know, processes cost memory and need to be scheduled.
</p>
<h2 id="hello-world">Hello World</h2>
<p>
Let's see how it would actually look like in code. We don't use I/O in this hello world, instead we use
another type of event - timers. Just click <i>"Run"</i> to see what happens.
</p>
<p>
We emulate this simple example in javascript, but if you want to see it live on your local machine with PHP,
just clone our <a href="https://github.com/amphp/hello-world"><code>hello-world</code></a> repository and run
<code>php timer.php</code>.
</p>
<pre><code class="language-php"><?php
function tick() {
echo "tick\n";
}
echo "before run()\n";
Amp\run(function() {
Amp\repeat("tick", $msInterval = 1000);
Amp\once("Amp\stop", $msDelay = 5000);
});
echo "after run()\n";</code></pre>
<p class="text-right">
<button class="btn btn-green" id="run"><i class="fa fa-play"></i> Run code sample</button>
</p>
<pre id="run-output"></pre>
<script>
var button = document.getElementById("run");
var output = document.getElementById("run-output");
var run = false;
button.addEventListener("click", function(e) {
output.textContent = "before run()\n";
button.disabled = true;
run = setInterval(tick, 1000);
setTimeout(stop, 5000);
});
function tick() {
output.textContent += "tick\n";
}
function stop() {
output.textContent += "after run()\n";
button.disabled = false;
clearInterval(run);
}
</script>
<h2 id="installation">Installation</h2>
<p>
We already have a good set of libraries and packages you can use. Not all of them have a documentation
yet, <a href="https://github.com/amphp/amphp.github.io">you're welcome to help</a>. You can install all
our libraries using <a href="https://getcomposer.org">Composer</a>. Just have a look at the blue top
menu listing the packages. It's indicated whether they have documentation here already or not through
the icon on the right.
</p>
<pre><code class="language-bash" id="install">composer require amphp/amp</code></pre>
<script>
var install = document.getElementById("install");
var packages = [
{% for repository in site.github.public_repositories %}
{% if repository.name != "amphp.github.io" and repository.name != "template" and repository.name != "design" and repository.name != "hello-world" %}
{{repository.name | jsonify}},
{% endif %}
{% endfor %}
"amp"
];
setInterval(function() {
install.textContent = "composer require amphp/" + packages[parseInt(Math.floor(Math.random() * packages.length))];
}, 2000);
</script>
<div class="tutorial-next">
Continue with <a href="/docs/amp/">Installing Amp</a>.
</div>
</div>