I am currently working on implementing a toy store server using Python, employing socket connections and a custom thread pool for handling concurrent client requests. However, I'm facing some challenges with managing concurrent requests efficiently.
Server Component: The server listens for incoming client requests over sockets. It takes the name of a toy as an argument and returns the dollar price of the item if it's in stock. If the item is not found, it returns -1, and if the item is found but not in stock, it returns 0.
A custom thread pool is implemented to handle multiple client connections concurrently.
Client Component:
The client connects to the server using a socket connection and issues random toy requests.
I've implemented a custom thread pool to manage client requests, but I'm unsure if it's handling concurrent requests optimally. The server does not receive any further requests after the first client request.
Server code:
import socket
import json
from threading import Thread, Lock
from collections import deque
class Server():
def __init__(self, host, port, num_threads):
self.items = {
"tux": {
"qty": 100,
"cost": 25.99
},
"whale": {
"qty": 100,
"cost": 19.99
}
}
self.lock = Lock()
self.request_queue = deque([])
self.thread_pool = [Thread(target=self.serve_request) for _ in range(num_threads)]
self.s = socket.socket()
self.s.bind((host, port))
print("socket binded to port", port)
self.s.listen(5)
print("socket is listening")
def get_item(self, item):
with self.lock:
if item not in self.items:
return -1
if self.items[item]['qty'] == 0:
return 0
self.items[item]['qty'] -= 1
return self.items[item]['cost']
def add_request(self, req):
data = req.recv(4096)
data = json.loads(data.decode('utf-8'))
cost = self.get_item(data['query'])
self.request_queue.append([req, cost])
def serve_request(self):
while True:
if self.request_queue:
req, cost = self.request_queue.popleft()
print("cost: ", cost)
req.send(str(cost).encode('utf-8'))
def run(self):
req, addr = self.s.accept()
for thread in self.thread_pool:
thread.start()
while True:
self.add_request(req)
print("request_queue: ", self.request_queue)
host = "127.0.0.1"
port = 12345
server = Server(host, port, 100)
server.run()
Client code:
import socket
import json
import random
def main():
host = "127.0.0.1"
port = 12345
s = socket.socket()
s.connect((host, port))
while True:
toys = ["tux", "whale"]
choice = random.choice(toys)
message = {"query": str(choice)}
serialzed_message = json.dumps(message)
print("requesting: ", choice)
s.send(serialzed_message.encode('utf-8'))
data = s.recv(4096)
print("Server replied: {}".format(str(data.decode('utf-8'))))
if __name__ == "__main__":
main()
Server.runthereq, addr = self.s.accept()must be in the while-loop to continually accept new requests.accept()calls should be issued in a loop. If you don't know how to use sockets at basic level, then there are plenty examples in the net. You may find an example even in the Python documentation.