SELECT auth_user.id, auth_user.first_name, auth_user.last_name, auth_user.email, auth_user.password, auth_user.registration_key, auth_user.reset_password_key, auth_user.registration_id, auth_user.alta,auth_user.plantel, auth_user.responsable, auth_user.nombre, auth_user.telefono, auth_user.autor, auth_user.foto, auth_user.foto_temp, auth_user.moderador, auth_user.descripcion, auth_user.facebook,auth_user.twitter, auth_user.linkedin, auth_user.gplus FROM auth_user WHERE (auth_user.id = 2) LIMIT 1 OFFSET 0;
select t.relname,l.locktype,page,virtualtransaction,pid,mode,granted from pg_locks l, pg_stat_all_tables t where l.relation=t.relid order by relation asc;
relname | locktype | page | virtualtransaction | pid | mode | granted
-----------------------------+----------+------+--------------------+------+-----------------+---------
pg_class | relation | | 70/908027 | 4421 | AccessShareLock | t
pg_index | relation | | 70/908027 | 4421 | AccessShareLock | t
pg_namespace | relation | | 70/908027 | 4421 | AccessShareLock | t
web2py_session_infosanpedro | relation | | 16/1858255 | 9865 | AccessShareLock | t
auth_user | relation | | 16/1858255 | 9865 | AccessShareLock | t
(5 rows)
def user(): if request.env.request_method == 'POST': email = request.post_vars.email.lower().strip() if request.post_vars.email else '' password = request.post_vars.password recordarme = bool(int(request.post_vars.recordarme or 0)) errores = [] if not email: errores.append(['email', 'Ingresa tu dirección de email']) if not password: errores.append(['password', 'Ingresa tu contraseña']) if errores: return response.json({'success': False, 'errores': errores})
usuario = db(db.auth_user.email.lower() == email).select().first() if not usuario: session.failed_login_attempt = True return response.json({ 'success': False, 'message': 'Login data invalid' }) elif usuario.registration_key: return response.json({ 'success': False, 'message': 'Registration is pending for confirmation' }) else: usuario = auth.login_bare(usuario.email, password) if not usuario: return response.json({ 'success': False, 'message': 'Login data invalid' }) session.auth.expiration = auth.settings.expiration if recordarme: session.auth.expiration = auth.settings.long_expiration session.auth.remember_me = True if response.cookies.get(response.session_id_name): response.cookies[response.session_id_name]["expires"] = session.auth.expiration try: db.auth_event.insert(time_stamp=request.now, client_ip=request.client, user_id=usuario.id, origin='auth', description='User %s Logged-in' % usuario.id) except: pass return response.json({'success': True})
Yes, in fact, I've been running that SQL command to check for locks, and sometimes I see that lock on other tables, but that other locks live for less than a second. However, when the problem happens, the lock on the auth_user and web2py_session tables remains there for the whole 60 seconds.
Traceback (most recent call last):
File "/var/www/medios/gluon/main.py", line 463, in wsgibase
session._try_store_in_db(request, response)
File "/var/www/medios/gluon/globals.py", line 1152, in _try_store_in_db
if not table._db(table.id == record_id).update(**dd):
File "/var/www/medios/gluon/packages/dal/pydal/objects.py", line 2117, in update
ret = db._adapter.update("%s" % table._tablename,self.query,fields)
File "/var/www/medios/gluon/packages/dal/pydal/adapters/base.py", line 988, in update
raise e
DatabaseError: query_wait_timeout
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
if auth.is_logged_in() and auth.user.responsable:
# ----------- THIS IS THE LINE WHERE THE CODE HANGS ----------
session.important_messages = cache.redis('important_messages-%s' % auth.user.id, lambda: get_important_messages(), time_expire=180)
def get_important_messages(): from gluon.contrib.simplejsonrpc import ServerProxy
webservice = ServerProxy('https://main-app-domain.com/ws/call/jsonrpc?token=XXX1')
try: result = webservice.get_account_info(CONFIG.customer_id) except Exception as e: result = []
return result
2018/04/17 15:08:22 [error] 23587#23587: *93711423 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX1 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:08:22 [error] 23587#23587: *93711449 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX2 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:08:36 [error] 23582#23582: *93711928 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX1 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:09:04 [error] 23582#23582: *93713029 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX3 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:09:16 [error] 23591#23591: *93713451 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX1 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:09:24 [error] 23582#23582: *93713819 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX4 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:09:25 [error] 23582#23582: *93713839 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX5 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:10:25 [error] 23582#23582: *93716003 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX1 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:12:34 [error] 23591#23591: *93720887 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX6 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:12:36 [error] 23590#23590: *93720938 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX7 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/17 15:12:50 [error] 23589#23589: *93721468 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX8 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/16 10:39:39 [error] 16600#16600: *89723537 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX7 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/16 10:40:10 [error] 16601#16601: *89724987 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX9 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/16 10:40:11 [error] 16602#16602: *89725040 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX9 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/16 16:59:46 [error] 17874#17874: *90771814 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX8 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/16 17:00:56 [error] 17877#17877: *90774663 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX8 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/16 17:01:11 [error] 17879#17879: *90775407 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX9 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"2018/04/15 13:46:46 [error] 11395#11395: *86829630 upstream timed out (110: Connection timed out) while reading response header from upstream, client: MY.OWN.SERVER.IP, server: main-app-domain.com, request: "POST /ws/call/jsonrpc?token=XXX9 HTTP/1.1", upstream: "uwsgi://unix:///tmp/medios.socket", host: "main-app-domain.com"
# -*- coding: utf-8 -*-
from gluon.tools import Service
service = Service()
def call(): if not request.vars.token or not db(db.websites.token == request.vars.token).count(): raise HTTP(403) session.forget() return service()
lambda: get_important_messages(), time_expire=180)
session.important_messages = cache.redis('important-messages', lambda: get_important_messages(), time_expire=180)
$ redis-cli
127.0.0.1:6379> DUMP w2p:myapp:important-messages-3
(nil)
127.0.0.1:6379> SET w2p:myapp:important-messages-3 "hello"
OK
127.0.0.1:6379> DUMP w2p:myapp:important-messages-3
"\x00\x05hello\x06\x00\xf5\x9f\xb7\xf6\x90a\x1c\x99"
127.0.0.1:6379> DEL w2p:myapp:important-messages-3
(integer) 1127.0.0.1:6379> DUMP w2p:myapp:important-messages-3
127.0.0.1:6379> DUMP w2p:myapp:important-messages-3
(nil)
r = cache.redis('important-messages-3', lambda: request.now, time_expire=30)
Thank you very much for your time Anthony.Yes, I use Redis with_lock=True.I checked but there is no *__lock key stored in Redis. I double checked that.But, giving you mentioned with_lock, I tried to set with_lock=False, and it worked.Then I set with_lock=True again, and it worked too.Apparently, the problem went away after executing the request one time with_lock=False, and then I could set it back to True and it kept working ok.I'm using an old version of web2py (2.10).
I see what you mean.But still, if my interpretation is correct, in those cases we should see the *__lock key stored.What is weird about my specific issue is that there was no *__lock key.Anyway, regardless upgrading web2py, now I'm wondering if I should set with_lock True or False. Do you have any suggestion? The book says:"Redis cache subsystem allows you to prevent the infamous "thundering herd problem": this is not active by default because usually you choose redis for speed, but at a negligible cost you can make sure that only one thread/process can set a value concurrently."I haven't found comments regarding when is best to use with_lock=True and when to use with_lock=False.
A quick comment about a couple of tests I did regarding RedisSession (that also has a "with_lock" argument).To the test, I updated web2py locally to version 2.16.1-stable+timestamp.2017.11.14.05.54.25And then I run my apps using:
- RedisSession(..., with_lock=False)
This is the way that I was already using it, and apps run normally (pretty fast because they do simple tasks)- RedisSession(..., with_lock=True)
Using this, the apps start responding with hughe delay; the same requests that usually took less than a second to complete, start tooking between 6 and 10 seconds.
A quick comment about a couple of tests I did regarding RedisSession (that also has a "with_lock" argument).To the test, I updated web2py locally to version 2.16.1-stable+timestamp.2017.11.14.05.54.25And then I run my apps using:
- RedisSession(..., with_lock=False)
This is the way that I was already using it, and apps run normally (pretty fast because they do simple tasks)- RedisSession(..., with_lock=True)
Using this, the apps start responding with hughe delay; the same requests that usually took less than a second to complete, start tooking between 6 and 10 seconds.That seems odd. This should have minimal effect on the time to complete a single request if there are no other simultaneous requests involving the same session. How are you testing?
db = DAL( 'postgres://%s:%s@%s/%s' % (CONFIG.db_user, CONFIG.db_user_password, CONFIG.db_host, CONFIG.db_name), migrate=False, lazy_tables=True, folder=os.path.join(CONFIG.path_datos, 'databases'))
_conn = RConn('localhost', 6379)
sessiondb = RedisSession( redis_conn=_conn, session_expiry=172800, # two days with_lock=True)
session.connect(request, response, db=sessiondb)
auth = Auth(globals(), db, hmac_key=Auth.get_or_create_key(filename=os.path.join(CONFIG.path_datos, 'auth.key')))
auth.define_tables()
# ... define all the tables# ... configure auth settings
It does look like the Redis session code puts a 2 second lock on the session when it is first read at the beginning of a request, so if a page makes multiple simultaneous Ajax requests when it loads, each request will take up to 2 seconds before the next can be processed (if I'm reading the code right, an update to the session will result in the lock being released, but if no update is made, it looks like you have to wait for the full 2 seconds to expire).Note, locking with Redis cache works differently -- the lock is held only during the time it takes to read from or write to the cache, not for the duration of the entire request or beyond.
I'm using an old web2py version (Version 2.10.3-stable+timestamp.2015.04.02.21.42.07).I already have plans to upgrade.But before, could I manually update only gluon/contrib/redis_*.py files?In your opinion, does that test worthwhile? Does it make any sense?