- Hands-On Reactive Programming with Python
- Romain Picard
- 552字
- 2021-06-24 18:25:22
Adding the program logic
Now that all the elements needed to implement the asynchronous reactive server are implemented, the application logic can be added. This part is implemented as a function that takes an object of observables as input and returns an object of observables as output. It is a component.
The following figure shows the reactivity diagram of this component:
The empty skeleton of this function is the following one:
def echo_server(source):
return {
'http': Observable.empty()
}
This component is implemented as a pure function. Its behavior depends only on the value of the input parameter; that is, the content of the http observable contained in the source object. For now, this function returns an empty observable. This will be completed once the body of the function is completed.
The first part of this component is the configuration and initialization of the HTTP server. This is done in a dedicated observable that contains the definition of the HTTP route and the request to start the server:
init = Observable.from_([
{
'what': 'add_route',
'methods': ['GET'],
'path': '/echo/{what}',
}, {
'what': 'start_server',
'host': 'localhost',
'port': 8080
}
])
The first item will add a new route for the GET method on the /echo/ path. Note the usage of a variable resource, the {what} part of the path, to retrieve the text to echo. The second items effectively start the server on localhost and port 8080.
The second part of the component consists of answering the echo requests. The echo requests come from the observable present in the http field of the source dictionary. The answer is simply built by mapping the source request item to a response item:
echo = source['http'] \
.map(lambda i: {
'what': 'response',
'status': 200,
'context': i['context'],
'data': i['match_info']['what'].encode('utf-8'),
})
The implementation is straightforward and consists of lambda. The returned item is a response item, with status 200 (the status code for OK in an HTTP response), and the data retrieved from the variable resource that was declared in the route. This value is retrieved from the match_info field of the request item. This text value must be encoded so that aiohttp can put it in the body of the response. The response items are available in the echo observable.
Now that all the logic is implemented, these two observables must be returned so that they can feed the HTTP driver. This is done with the merge operator:
return {
'http': Observable.merge(init, echo),
}
The full code of the echo component is the following one:
def echo_server(source):
init = Observable.from_([
{
'what': 'add_route',
'methods': ['GET'],
'path': '/echo/{what}',
}, {
'what': 'start_server',
'host': 'localhost',
'port': 8080
}
])
echo = source['http'] \
.map(lambda i: {
'what': 'response',
'status': 200,
'context': i['context'],
'data': i['match_info']['what'].encode('utf-8'),
})
return {
'http': Observable.merge(init, echo),
}
The full code of the server is available in the rx_http_echo.py script. It can be tested the same way as with the previous implementation of asyncio. Start the server in a terminal, and then in another Terminal, use curl to test it:
$ curl http://localhost:8080/echo/hello
hello
$ curl http://localhost:8080/echo/foo
foo
This implementation does not stop the server. As an exercise, you can add another route such as /exit that will ask the HTTP driver to stop the server.
- Windows Vista基礎與應用精品教程
- Designing Purpose:Built Drones for Ardupilot Pixhawk 2.1
- 每天5分鐘玩轉Kubernetes
- 混沌工程:復雜系統韌性實現之道
- Linux操作系統應用編程
- 數據中心系統工程及應用
- Windows Server 2019 Administration Fundamentals
- Linux內核觀測技術BPF
- iOS 8開發指南
- Linux操作系統
- VMware Horizon Mirage Essentials
- 再也不踩坑的kubernetes實戰指南
- Learning Joomla! 3 Extension Development(Third Edition)
- 電腦辦公(Windows 7 + Office 2013)入門與提高
- Getting Started with Citrix XenApp 6.5