Skip to content

Commit 913616f

Browse files
committed
Sockets and gzip
1 parent 40c76c8 commit 913616f

7 files changed

Lines changed: 102 additions & 68 deletions

File tree

api/pysica_api_sockets.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import socket
22
import json
3+
import zlib
34
from struct import unpack, pack
45

56

@@ -28,6 +29,10 @@ def cache_add(element_id, data, data_type, timeout=None, compress=None, user_id=
2829
try:
2930
cp = SocketHandler()
3031
cp.connect(socket_file, server, port)
32+
except Exception as ex:
33+
return Response({"success": False, "message": "Unable to connect to cache server. Error message: " + str(ex)})
34+
35+
try:
3136
# Prepare package
3237
data = {
3338
'target': "add",
@@ -42,14 +47,18 @@ def cache_add(element_id, data, data_type, timeout=None, compress=None, user_id=
4247
response = cp.send_data(data, buffer_size=buffer_size)
4348
cp.close()
4449
return Response(json.loads(response))
45-
except:
46-
return Response({"success": False, "message": "Unable to connect to cache server."})
50+
except Exception as ex:
51+
return Response({"success": False, "message": "Unable to add element to cache. Error message: " + str(ex)})
4752

4853

4954
def cache_get(element_id=None, data_type=None, user_id=None, reset_timeout=False, timeout=None, socket_file=None, server="localhost", port=4444, buffer_size=4096):
5055
try:
5156
cp = SocketHandler()
5257
cp.connect(socket_file, server, port)
58+
except Exception as ex:
59+
return Response({"success": False, "message": "Unable to connect to cache server. Error message: " + str(ex)})
60+
61+
try:
5362
# Prepare package
5463
data = {
5564
'target': "get",
@@ -63,19 +72,22 @@ def cache_get(element_id=None, data_type=None, user_id=None, reset_timeout=False
6372
response = cp.get_data(data, buffer_size=buffer_size)
6473
cp.close()
6574
return Response(json.loads(response))
66-
except:
67-
return Response({"success": False, "message": "Unable to connect to cache server."})
75+
except Exception as ex:
76+
return Response({"success": False, "message": "Unable to get element from cache. Error message: " + str(ex)})
6877

6978

7079
def cache_remove(element_id, user_id=None, return_elem=False, socket_file=None, server="localhost", port=4444, buffer_size=4096):
80+
# Get data
81+
if return_elem:
82+
element = cache_get(element_id=element_id, user_id=user_id, socket_file=socket_file, server=server, port=port, buffer_size=buffer_size)
83+
7184
try:
72-
# Get data
73-
if return_elem:
74-
element = cache_get(element_id=element_id, user_id=user_id, socket_file=socket_file, server=server, port=port, buffer_size=buffer_size)
75-
# Remove element
7685
cp = SocketHandler()
7786
cp.connect(socket_file, server, port)
78-
print("sadasds")
87+
except Exception as ex:
88+
return Response({"success": False, "message": "Unable to connect to cache server. Error message: " + str(ex)})
89+
90+
try:
7991
# Prepare package
8092
data={
8193
'target': "remove",
@@ -90,14 +102,18 @@ def cache_remove(element_id, user_id=None, return_elem=False, socket_file=None,
90102

91103
cp.close()
92104
return Response(response)
93-
except:
94-
return Response({"success": False, "message": "Unable to connect to cache server."})
105+
except Exception as ex:
106+
return Response({"success": False, "message": "Unable to remove element from cache. Error message: " + str(ex)})
95107

96108

97109
def cache_reset(element_id, timeout=None, user_id=None, socket_file=None, server="localhost", port=4444, buffer_size=4096):
98110
try:
99111
cp = SocketHandler()
100112
cp.connect(socket_file, server, port)
113+
except Exception as ex:
114+
return Response({"success": False, "message": "Unable to connect to cache server. Error message: " + str(ex)})
115+
116+
try:
101117
# Prepare package
102118
data={
103119
'target': "reset",
@@ -109,16 +125,16 @@ def cache_reset(element_id, timeout=None, user_id=None, socket_file=None, server
109125
response = cp.send_data(data, buffer_size=buffer_size)
110126
cp.close()
111127
return Response(json.loads(response))
112-
except:
113-
return Response({"success": False, "message": "Unable to connect to cache server."})
128+
except Exception as ex:
129+
return Response({"success": False, "message": "Unable to reset element at cache. Error message: " + str(ex)})
114130

115131

116132
class SocketHandler:
117133
def __init__(self):
118134
self.socket = None
119135

120136
def connect(self, socket_file=None, server_ip=None, server_port=None):
121-
if socket_file is not None:
137+
if socket_file is not None and socket_file != "":
122138
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
123139
self.socket.connect(socket_file)
124140
else:
@@ -131,7 +147,7 @@ def close(self):
131147
self.socket = None
132148

133149
def send_data(self, data, buffer_size=4096):
134-
data = json.dumps(data)
150+
data = zlib.compress(json.dumps(data))
135151
# use struct to make sure we have a consistent endianness on the length
136152
length = pack('>Q', len(data))
137153
# sendall to make sure it blocks if there's back-pressure on the socket
@@ -146,10 +162,10 @@ def send_data(self, data, buffer_size=4096):
146162
# to do it all in one go, so I believe.
147163
to_read = data_length - len(data)
148164
data += self.socket.recv(buffer_size if to_read > buffer_size else to_read)
149-
return data
165+
return zlib.decompress(data)
150166

151167
def get_data(self, data, buffer_size=4096):
152-
data = json.dumps(data)
168+
data = zlib.compress(json.dumps(data))
153169
# use struct to make sure we have a consistent endianness on the length
154170
length = pack('>Q', len(data))
155171
# sendall to make sure it blocks if there's back-pressure on the socket
@@ -164,7 +180,7 @@ def get_data(self, data, buffer_size=4096):
164180
# to do it all in one go, so I believe.
165181
to_read = data_length - len(data)
166182
data += self.socket.recv(buffer_size if to_read > buffer_size else to_read)
167-
return data
183+
return zlib.decompress(data)
168184

169185

170186
class Response(object):
@@ -200,5 +216,3 @@ def __str__(self):
200216

201217
def __repr__(self):
202218
return self.__str__()
203-
204-

docker/Dockerfile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ MAINTAINER Rafael Hernandez <https://github.com/fikipollo>
1212
################## BEGIN INSTALLATION ######################
1313
#INSTALL THE DEPENDENCIES
1414

15-
COPY configs/* /tmp/
16-
1715
RUN set -x \
1816
&& apk --update --no-cache add make unzip \
1917
&& apk --update --no-cache --virtual .build-dep add build-base linux-headers tzdata \
@@ -26,9 +24,12 @@ RUN set -x \
2624
&& pip install --no-cache-dir APScheduler \
2725
&& pip install --no-cache-dir https://github.com/unbit/uwsgi/archive/uwsgi-2.0.zip#egg=uwsgi \
2826
&& apk del .build-dep \
29-
&& unzip /tmp/pysica.zip -d /tmp/pysica \
27+
&& mkdir -p /var/www/
28+
29+
COPY configs/* /tmp/
30+
31+
RUN unzip /tmp/pysica.zip -d /tmp/pysica \
3032
&& mv /tmp/pysica_uwsgi.ini /var/ \
31-
&& mkdir -p /var/www/ \
3233
&& mv /tmp/pysica /var/www/pysica \
3334
&& mv /tmp/entrypoint.sh /usr/bin/entrypoint.sh \
3435
&& chmod +x /usr/bin/entrypoint.sh \

docker/configs/entrypoint.sh

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ SERVER_HOST_NAME="${SERVER_HOST_NAME:-0.0.0.0}"
1818

1919
# Change the default configuration based on environment
2020
sed -i 's/"SERVER_MODE".*/"SERVER_MODE" : "'${SERVER_MODE}'",/' /var/www/pysica/conf/server.cfg
21-
sed -i 's/"SERVER_SOCKET_FILE".*/"SERVER_SOCKET_FILE" : "'${SERVER_SOCKET_FILE}'",/' /var/www/pysica/conf/server.cfg
21+
sed -i 's#"SERVER_SOCKET_FILE".*#"SERVER_SOCKET_FILE" : "'${SERVER_SOCKET_FILE}'",#' /var/www/pysica/conf/server.cfg
2222
sed -i 's/"SERVER_BUFFER_SIZE".*/"SERVER_BUFFER_SIZE" : '${SERVER_BUFFER_SIZE}',/' /var/www/pysica/conf/server.cfg
2323
sed -i 's/"SERVER_HOST_NAME".*/"SERVER_HOST_NAME" : "'${SERVER_HOST_NAME}'",/' /var/www/pysica/conf/server.cfg
2424

25-
2625
echo "#---------------------------------------------------------------------------------------------------"
2726
echo "# Welcome to PySiCa (Python Simple Cache)"
2827

@@ -33,7 +32,7 @@ if [[ "$SERVER_MODE" == "socket_based" ]]; then
3332
echo "# the server.cfg file. Available options are 'web_based' for RESTFUL mode based on HTTP "
3433
echo "# and 'socket_based' to use pure socket communication."
3534
echo "#---------------------------------------------------------------------------------------------------"
36-
python /var/www/pysica/server_sockets.py
35+
python /var/www/pysica/server_sockets.py &
3736
else
3837
echo "# Cache server is running as web server"
3938
echo "# To change the running mode, please set the value for the variable SERVER_MODE in the"
@@ -45,8 +44,8 @@ else
4544
kill -9 `cat /tmp/pysica.pid`
4645
rm /tmp/pysica.*
4746
fi
48-
4947
uwsgi --ini /var/pysica_uwsgi.ini
50-
tail -f /var/log/pysica/cache.log
5148
fi
5249

50+
echo "Listening to /var/log/pysica/cache.log"
51+
tail -f /var/log/pysica/cache.log

docker/configs/pysica.zip

397 Bytes
Binary file not shown.

docker/deploy.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ rm -rf venv docker test .git .idea
1414
rm conf/*
1515
rm *.pyc
1616

17-
sed -i 's/\/tmp\/cache/\/var\/log\/pysica\/cache/g' default/server.default.cfg
18-
sed -i 's/"DEBUG" : true/"DEBUG" : false/g' default/server.default.cfg
17+
sed -i 's#/tmp/cache#/var/log/pysica/cache#g' default/server.default.cfg
18+
sed -i 's/"DEBUG".*/"DEBUG" : false,/' default/server.default.cfg
1919

2020
echo "Compressing server application... "
2121
zip -r ../pysica.zip *

server_http.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,12 @@ def __init__(self):
2020
# SERVER DEFINITION
2121
# ------------------------------------------------------------------------------------------
2222
self.settings = self.read_settings_file()
23-
23+
self.buffer_size = 0
2424
# Enable the logging to file for production
25-
logger = None
26-
if not self.settings.get("DEBUG", True):
27-
try:
28-
handler = RotatingFileHandler(self.settings.get("LOG_FILE"), maxBytes=31457280, backupCount=5)
29-
handler.setLevel(logging.INFO)
30-
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s : %(funcName)s - %(message)s'))
31-
logger = logging.getLogger(__name__)
32-
logger.root.addHandler(handler)
33-
except Exception as e:
34-
raise Exception("Unable to open log file " + self.settings.get("LOG_FILE", "LOG FILE NOT SPECIFIED") + ". Error message: " + str(e))
35-
25+
self.logger= self.configure_logging()
26+
# Create the instance for the cache
3627
self.cache_instance = PySiCa(
37-
logger=logger,
28+
logger=self.logger,
3829
timeout=self.settings.get("TIMEOUT"),
3930
compress=self.settings.get("COMPRESS"),
4031
max_elems=self.settings.get("MAX_ELEMS"),
@@ -136,6 +127,22 @@ def read_settings_file(self):
136127

137128
return settings
138129

130+
def configure_logging(self):
131+
if not self.settings.get("DEBUG", True):
132+
try:
133+
logger = logging.getLogger()
134+
logger.handlers=[]
135+
#
136+
handler = RotatingFileHandler(self.settings.get("LOG_FILE"), maxBytes=31457280, backupCount=5)
137+
handler.propagate = False
138+
handler.setLevel(logging.INFO)
139+
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s : %(funcName)s - %(message)s'))
140+
logger.root.addHandler(handler)
141+
return logger
142+
except Exception as e:
143+
raise Exception("Unable to open log file " + self.settings.get("LOG_FILE", "LOG FILE NOT SPECIFIED") + ". Error message: " + str(e))
144+
else:
145+
return logging.root
139146

140147
api = application = falcon.API()
141148
application.req_options.auto_parse_form_urlencoded = True

0 commit comments

Comments
 (0)