Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3 changes #947

Open
dsuch opened this issue Apr 17, 2019 · 29 comments

Comments

Projects
None yet
2 participants
@dsuch
Copy link
Collaborator

commented Apr 17, 2019

No description provided.

@dsuch dsuch self-assigned this Apr 17, 2019

@dsuch dsuch added this to the 3.1 milestone Apr 17, 2019

@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 17, 2019

@jsabater - I pushed a commit that uses gevent's patching earlier in the server's startup process.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented Apr 17, 2019

The changes worked fine:

$ /opt/zato/env/qs-1/zato-qs-start.sh
Starting Zato cluster quickstart-726934
Checking configuration
[1/8] Redis connection OK
[2/8] SQL ODB connection OK
[3/8] Checking TCP ports availability
[4/8] Load-balancer started
[5/8] server1 started
[6/8] server2 started
[7/8] Scheduler started
[8/8] Web admin started
Zato cluster quickstart-726934 started
Visit https://zato.io/support for more information and support options

$ ps -u zato x
  PID TTY      STAT   TIME COMMAND
   44 pts/0    S      0:00 -su
  131 pts/0    S      0:02 /opt/zato/zato/code/bin/python -m zato.agent.load_balancer.main /opt/zato/env/qs-1/load-balancer/config/repo fg=FalseZATO_ZATO_ZATOsync_internal=FalseZATO_ZATO_ZATOsecret_key=
  173 ?        Ss     0:00 haproxy -D -f /opt/zato/env/qs-1/load-balancer/config/repo/zato.config -p /opt/zato/env/qs-1/load-balancer/pidfile
  191 pts/0    Sl     0:02 gunicorn: master [gunicorn]
  232 pts/0    Sl     0:02 gunicorn: master [gunicorn]
  275 pts/0    Sl     0:02 /opt/zato/zato/code/bin/python -m zato.scheduler.main fg=FalseZATO_ZATO_ZATOsync_internal=FalseZATO_ZATO_ZATOsecret_key=
  307 pts/0    S      0:02 /opt/zato/zato/code/bin/python -m zato.admin.main fg=FalseZATO_ZATO_ZATOsync_internal=FalseZATO_ZATO_ZATOsecret_key=
  353 pts/0    R+     0:00 ps -u zato x

In my case this is a Docker container that has Redis inside and PostgreSQL outside. I'll install my prototype application now and keep testing now.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

Hi again. I am seeing this error on the server1 log file (/opt/zato/env/qs-1/server1/logs/server.log) after start:

2019-04-22 11:25:10,126 - �[1;37mINFO�[0m - 708:MainThread - gunicorn.main:0 - Starting gunicorn 19.9.0
2019-04-22 11:25:10,130 - �[1;37mINFO�[0m - 708:MainThread - gunicorn.main:0 - Listening at: http://0.0.0.0:17010 (708)
2019-04-22 11:25:10,131 - �[1;37mINFO�[0m - 708:MainThread - gunicorn.main:0 - Using worker: gevent
2019-04-22 11:25:10,135 - �[1;37mINFO�[0m - 738:MainThread - gunicorn.main:0 - Booting worker with pid: 738
2019-04-22 11:25:10,467 - �[1;31mERROR�[0m - 738:MainThread - zato.common.odb.api:0 - Could not find server in ODB, token:`b'cdfbe224990643838892070a526b3d9f'`
2019-04-22 11:25:10,468 - �[1;31mERROR�[0m - 738:MainThread - gunicorn.main:0 - Exception in worker process
Traceback (most recent call last):
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1780, in execute
    ps = cache['ps'][key]
KeyError: ('SELECT server.id AS server_id, server.name AS server_name, server.host AS server_host, server.bind_host AS server_bind_host, server.bind_port AS server_bind_port, server.preferred_address AS server_preferred_address, server.crypto_use_tls AS server_crypto_use_tls, server.last_join_status AS server_last_join_status, server.last_join_mod_date AS server_last_join_mod_date, server.last_join_mod_by AS server_last_join_mod_by, server.up_status AS server_up_status, server.up_mod_date AS server_up_mod_date, server.token AS server_token, server.opaque1 AS server_opaque1, server.cluster_id AS server_cluster_id \nFROM server \nWHERE server.token = %s', ((17, 1, <function bytea_send at 0x7f64aa4a5e18>),))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 508, in do_execute
    cursor.execute(statement, parameters)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 884, in execute
    self._c.execute(self, operation, args)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1839, in execute
    self.handle_messages(cursor)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1978, in handle_messages
    raise self.error
pg8000.core.ProgrammingError: ('ERROR', 'ERROR', '42883', 'operator does not exist: character varying = bytea', 'No operator matches the given name and argument types. You might need to add explicit type casts.', '642', 'parse_oper.c', '731', 'op_error')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/zato/zato/code/lib/python3.6/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    self.cfg.post_fork(self, worker)
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/parallel/__init__.py", line 906, in post_fork
    ParallelServer.start_server(worker.app.zato_wsgi_app, arbiter.zato_deployment_key)
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/parallel/__init__.py", line 453, in start_server
    server = self.odb.fetch_server(self.config.odb_data)
  File "/opt/zato/zato/code/zato-common/src/zato/common/odb/api.py", line 477, in fetch_server
    filter(Server.token == self.token).\
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2894, in one
    ret = self.one_or_none()
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2864, in one_or_none
    ret = list(self)
  File "/opt/zato/zato/code/zato-common/src/zato/common/odb/api.py", line 114, in __iter__
    it = super(WritableTupleQuery, self).__iter__()
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2935, in __iter__
    return self._execute_and_instances(context)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2958, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 948, in execute
    return meth(self, multiparams, params)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
    context)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
    exc_info
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
    raise value.with_traceback(tb)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 508, in do_execute
    cursor.execute(statement, parameters)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 884, in execute
    self._c.execute(self, operation, args)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1839, in execute
    self.handle_messages(cursor)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1978, in handle_messages
    raise self.error
sqlalchemy.exc.ProgrammingError: (pg8000.core.ProgrammingError) ('ERROR', 'ERROR', '42883', 'operator does not exist: character varying = bytea', 'No operator matches the given name and argument types. You might need to add explicit type casts.', '642', 'parse_oper.c', '731', 'op_error') [SQL: 'SELECT server.id AS server_id, server.name AS server_name, server.host AS server_host, server.bind_host AS server_bind_host, server.bind_port AS server_bind_port, server.preferred_address AS server_preferred_address, server.crypto_use_tls AS server_crypto_use_tls, server.last_join_status AS server_last_join_status, server.last_join_mod_date AS server_last_join_mod_date, server.last_join_mod_by AS server_last_join_mod_by, server.up_status AS server_up_status, server.up_mod_date AS server_up_mod_date, server.token AS server_token, server.opaque1 AS server_opaque1, server.cluster_id AS server_cluster_id \nFROM server \nWHERE server.token = %s'] [parameters: (b'cdfbe224990643838892070a526b3d9f',)] (Background on this error at: http://sqlalche.me/e/f405)
2019-04-22 11:25:10,474 - �[1;37mINFO�[0m - 738:MainThread - gunicorn.main:0 - Worker exiting (pid: 738)
2019-04-22 11:25:10,475 - �[1;37mINFO�[0m - 738:MainThread - zato:0 - Closing IPC (/pubsub/pid)
2019-04-22 11:25:10,475 - �[1;37mINFO�[0m - 738:MainThread - zato:0 - Closing IPC (/connector/config)
2019-04-22 11:25:10,475 - �[1;37mINFO�[0m - 738:MainThread - zato.server.base.parallel:0 - Stopping server process (None:738) (738)

Here is the process status after starting the cluster (same command as in the previous comment):

$ ps --user zato x
  PID TTY      STAT   TIME COMMAND
   16 pts/0    S      0:00 -su
  547 pts/1    S+     0:00 -su
  648 pts/0    S      0:02 /opt/zato/zato/code/bin/python -m zato.agent.load_balancer.main /opt/zato/env/qs-1/load-balancer/config/repo fg=FalseZATO_ZATO_ZATOsync_internal=FalseZATO_ZATO_ZATOsecret_key=
  690 ?        Ss     0:00 haproxy -D -f /opt/zato/env/qs-1/load-balancer/config/repo/zato.config -p /opt/zato/env/qs-1/load-balancer/pidfile
  708 pts/0    Sl     0:02 gunicorn: master [gunicorn]
  749 pts/0    Sl     0:02 gunicorn: master [gunicorn]
  790 pts/0    Sl     0:02 /opt/zato/zato/code/bin/python -m zato.scheduler.main fg=FalseZATO_ZATO_ZATOsync_internal=FalseZATO_ZATO_ZATOsecret_key=
  822 pts/0    S      0:02 /opt/zato/zato/code/bin/python -m zato.admin.main fg=FalseZATO_ZATO_ZATOsync_internal=FalseZATO_ZATO_ZATOsecret_key=
  864 pts/0    R+     0:00 ps --user zato x
@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 22, 2019

Thanks - this is something that I saw myself yesterday and dealt with accordingly. Are you sure you are at least on Zato 3.1pre1+rev.236b6758b-py3.6.7?

@jsabater

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

It's working fine now, even when using --sync-internal. I'll keep on testing... 👍

@jsabater

This comment has been minimized.

Copy link
Contributor

commented Apr 27, 2019

I run into this unexpected keyword argument 'pool_maxsize' error after doing the following:

  1. Starting the container (PostgreSQL and Redis outside, already started). The container starts empty (i.e. no services running, just a prompt).
  2. Changing dir to /opt/zato/zato/code and running ./update.sh.
  3. Changing to the home directory /opt/zato and running these commands:
$ zato start env/qs-1/server1/ --sync-internal
OK
$ zato start env/qs-1/server2/ --sync-internal
OK

I found this on the /opt/zato/env/qs-1/server1/logs/server.log and /opt/zato/env/qs-1/server2/logs/server.log log files:

2019-04-27 18:44:01,067 - ^[[1;37mINFO^[[0m - 190:MainThread - gunicorn.main:0 - Starting gunicorn 19.9.0 
2019-04-27 18:44:01,084 - ^[[1;37mINFO^[[0m - 190:MainThread - gunicorn.main:0 - Listening at: http://0.0.0.0:17010 (190) 
2019-04-27 18:44:01,085 - ^[[1;37mINFO^[[0m - 190:MainThread - gunicorn.main:0 - Using worker: gevent 
2019-04-27 18:44:01,096 - ^[[1;37mINFO^[[0m - 214:MainThread - gunicorn.main:0 - Booting worker with pid: 214 
2019-04-27 18:44:01,822 - ^[[1;37mINFO^[[0m - 214:MainThread - zato.server.base.parallel:0 - Preferred address of `server1@quickstart-314729` (pid: 214) is `http://172.17.0.1:17010` 
2019-04-27 18:44:03,923 - ^[[1;37mINFO^[[0m - 214:MainThread - zato.server.service.store:0 - Deploying and caching internal services (server1) 
2019-04-27 18:44:07,188 - ^[[1;37mINFO^[[0m - 214:MainThread - zato.server.service.store:0 - Deployed and cached 536 internal services (6.1 MB) (server1) 
2019-04-27 18:44:07,189 - ^[[1;37mINFO^[[0m - 214:MainThread - zato.server.base.parallel:0 - Deploying user-defined services (server1) 
2019-04-27 18:44:07,228 - ^[[1;37mINFO^[[0m - 214:MainThread - zato.server.base.parallel:0 - Deployed 0 user-defined services  (server1) 
2019-04-27 18:44:08,578 - ^[[1;31mERROR^[[0m - 214:MainThread - gunicorn.main:0 - Exception in worker process 
Traceback (most recent call last): 
  File "/opt/zato/zato/code/lib/python3.6/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker 
    self.cfg.post_fork(self, worker) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/parallel/__init__.py", line 908, in post_fork 
    ParallelServer.start_server(worker.app.zato_wsgi_app, arbiter.zato_deployment_key) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/parallel/__init__.py", line 524, in start_server 
    self.worker_store.init() 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 357, in init 
    self.init_http_soap() 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 543, in init_http_soap 
    wrapper = self._http_soap_wrapper_from_config(config_data.config) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 493, in _http_soap_wrapper_from_config 
    return HTTPSOAPWrapper(wrapper_config) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/connection/http_soap/outgoing.py", line 202, in __init__ 
    super(HTTPSOAPWrapper, self).__init__(config, requests_module) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/connection/http_soap/outgoing.py", line 68, in __init__ 
    self.session = requests_session(pool_maxsize=self.config['pool_size']) 
TypeError: __init__() got an unexpected keyword argument 'pool_maxsize' 
2019-04-27 18:44:08,586 - ^[[1;37mINFO^[[0m - 214:MainThread - gunicorn.main:0 - Worker exiting (pid: 214) 
2019-04-27 18:44:08,587 - ^[[1;37mINFO^[[0m - 214:MainThread - zato:0 - Closing IPC (/pubsub/pid) 
2019-04-27 18:44:08,587 - ^[[1;37mINFO^[[0m - 214:MainThread - zato:0 - Closing IPC (/connector/config) 
2019-04-27 18:44:08,597 - ^[[1;37mINFO^[[0m - 214:MainThread - zato.server.base.parallel:0 - Stopping server process (server1:214) (214)
@jsabater

This comment has been minimized.

Copy link
Contributor

commented Apr 27, 2019

After that I executed the following commands:

$ zato stop env/qs-1/server1/ 
Server `/opt/zato/env/qs-1/server1` shutting down
$ zato stop env/qs-1/server2/
Server `/opt/zato/env/qs-1/server2` shutting down
$ >| /opt/zato/env/qs-1/server1/logs/server.log
$ >| /opt/zato/env/qs-1/server2/logs/server.log
$ /opt/zato/env/qs-1/zato-qs-start.sh 
Starting Zato cluster quickstart-314729
Checking configuration
[1/8] Redis connection OK
[2/8] SQL ODB connection OK
[3/8] Checking TCP ports availability
[4/8] Load-balancer started
[5/8] server1 started
[6/8] server2 started
[7/8] Scheduler started
[8/8] Web admin started
Zato cluster quickstart-314729 started
Visit https://zato.io/support for more information and support options

And I found the same error on the log files:

2019-04-27 18:51:21,402 - ^[[1;37mINFO^[[0m - 440:MainThread - gunicorn.main:0 - Starting gunicorn 19.9.0 
2019-04-27 18:51:21,409 - ^[[1;37mINFO^[[0m - 440:MainThread - gunicorn.main:0 - Listening at: http://0.0.0.0:17010 (440) 
2019-04-27 18:51:21,409 - ^[[1;37mINFO^[[0m - 440:MainThread - gunicorn.main:0 - Using worker: gevent 
2019-04-27 18:51:21,420 - ^[[1;37mINFO^[[0m - 480:MainThread - gunicorn.main:0 - Booting worker with pid: 480 
2019-04-27 18:51:22,061 - ^[[1;37mINFO^[[0m - 480:MainThread - zato.server.base.parallel:0 - Preferred address of `server1@quickstart-314729` (pid: 480) is `http://172.17.0.1:17010` 
2019-04-27 18:51:24,131 - ^[[1;37mINFO^[[0m - 480:MainThread - zato.server.service.store:0 - Deploying cached internal services (server1) 
2019-04-27 18:51:26,354 - ^[[1;37mINFO^[[0m - 480:MainThread - zato.server.service.store:0 - Deployed 536 cached internal services (server1) 
2019-04-27 18:51:26,355 - ^[[1;37mINFO^[[0m - 480:MainThread - zato.server.base.parallel:0 - Deploying user-defined services (server1) 
2019-04-27 18:51:26,401 - ^[[1;37mINFO^[[0m - 480:MainThread - zato.server.base.parallel:0 - Deployed 0 user-defined services  (server1) 
2019-04-27 18:51:28,506 - ^[[1;31mERROR^[[0m - 480:MainThread - gunicorn.main:0 - Exception in worker process 
Traceback (most recent call last): 
  File "/opt/zato/zato/code/lib/python3.6/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker 
    self.cfg.post_fork(self, worker) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/parallel/__init__.py", line 908, in post_fork 
    ParallelServer.start_server(worker.app.zato_wsgi_app, arbiter.zato_deployment_key) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/parallel/__init__.py", line 524, in start_server 
    self.worker_store.init() 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 357, in init 
    self.init_http_soap() 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 543, in init_http_soap 
    wrapper = self._http_soap_wrapper_from_config(config_data.config) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 493, in _http_soap_wrapper_from_config 
    return HTTPSOAPWrapper(wrapper_config) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/connection/http_soap/outgoing.py", line 202, in __init__ 
    super(HTTPSOAPWrapper, self).__init__(config, requests_module) 
  File "/opt/zato/zato/code/zato-server/src/zato/server/connection/http_soap/outgoing.py", line 68, in __init__ 
    self.session = requests_session(pool_maxsize=self.config['pool_size']) 
TypeError: __init__() got an unexpected keyword argument 'pool_maxsize' 
2019-04-27 18:51:28,509 - ^[[1;37mINFO^[[0m - 480:MainThread - gunicorn.main:0 - Worker exiting (pid: 480) 
2019-04-27 18:51:28,510 - ^[[1;37mINFO^[[0m - 480:MainThread - zato:0 - Closing IPC (/pubsub/pid) 
2019-04-27 18:51:28,511 - ^[[1;37mINFO^[[0m - 480:MainThread - zato:0 - Closing IPC (/connector/config) 
2019-04-27 18:51:28,522 - ^[[1;37mINFO^[[0m - 480:MainThread - zato.server.base.parallel:0 - Stopping server process (server1:480) (480)
@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 27, 2019

The root cause is that some of the patches (to the requests library) were not applied. This is, I think a one-time situation, because it just so happened that I updated requests to 2.21.0 recently and in this particular case you need a full install.sh instead of update.sh.

Normally, this will not be required, but since this is still a development version, I just ask you for install.sh instead of update.sh.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented Apr 27, 2019

That fixed the issue. Thanks!

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 2, 2019

I just found this error on the logs when hot-deploying a module with a number of services:

2019-05-02 12:37:18,563 - �[1;31mERROR�[0m - 306:DummyThread-30 - zato:0 - Could not handle broker msg:`Bunch(action='102200', cid='4dee0173a87d24709e1cea47', msg_type='0002', package_id=47, payload={'package_id': 47}, service='zato.hot-deploy.create')`, e:`Traceback (most recent call last):
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 508, in do_execute
    cursor.execute(statement, parameters)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 861, in execute
    self._c.execute(self, operation, args)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1907, in execute
    self.handle_messages(cursor)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1974, in handle_messages
    raise self.error
pg8000.core.IntegrityError: {'S': 'ERROR', 'V': 'ERROR', 'C': '23505', 'M': 'duplicate key value violates unique constraint "service_name_cluster_id_key"', 'D': 'Key (name, cluster_id)=(rate.delete, 1) already exists.', 's': 'public', 't': 'service', 'n': 'service_name_cluster_id_key', 'F': 'nbtinsert.c', 'L': '535', 'R': '_bt_check_unique'}

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/zato/zato/code/zato-broker/src/zato/broker/__init__.py", line 52, in on_broker_msg
    getattr(self, handler)(msg)
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 1766, in on_broker_msg_HOT_DEPLOY_CREATE_SERVICE
    serialize=False, needs_response=True)
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 1757, in on_broker_msg_hot_deploy
    return self.on_message_invoke_service(msg, 'hot-deploy', 'HOT_DEPLOY_{}'.format(action), args, **kwargs)
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 1550, in on_message_invoke_service
    environ=msg.get('environ'))
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/__init__.py", line 606, in update_handle
    raise e if isinstance(e, Exception) else Exception(e)
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/__init__.py", line 554, in update_handle
    self._invoke(service, channel)
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/__init__.py", line 454, in _invoke
    service.handle()
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/internal/hot_deploy/__init__.py", line 225, in handle
    self.response.payload.services_deployed = self.deploy_package(self.request.input.package_id, session)
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/internal/hot_deploy/__init__.py", line 181, in deploy_package
    return self._deploy_package(session, package_id, dp.payload_name, dp.payload)
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/internal/hot_deploy/__init__.py", line 155, in _deploy_package
    services_deployed = self._deploy_file(current_work_dir, payload, file_name)
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/internal/hot_deploy/__init__.py", line 131, in _deploy_file
    info = self.server.service_store.import_services_from_anywhere(file_name, current_work_dir)
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/store.py", line 743, in import_services_from_anywhere
    self._store_in_odb(info.to_process)
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/store.py", line 660, in _store_in_odb
    needs_commit = self._store_services_in_odb(session, batch_indexes, to_process)
  File "/opt/zato/zato/code/zato-server/src/zato/server/service/store.py", line 585, in _store_services_in_odb
    self.odb.add_services(session, [elem.to_dict() for elem in to_add])
  File "/opt/zato/zato/code/zato-common/src/zato/common/odb/api.py", line 714, in add_services
    session.execute(ServiceTableInsert().values(data))
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 1176, in execute
    bind, close_with_result=True).execute(clause, params or {})
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 948, in execute
    return meth(self, multiparams, params)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
    context)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
    exc_info
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
    raise value.with_traceback(tb)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 508, in do_execute
    cursor.execute(statement, parameters)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 861, in execute
    self._c.execute(self, operation, args)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1907, in execute
    self.handle_messages(cursor)
  File "/opt/zato/zato/code/lib/python3.6/site-packages/pg8000/core.py", line 1974, in handle_messages
    raise self.error
sqlalchemy.exc.IntegrityError: (pg8000.core.IntegrityError) {'S': 'ERROR', 'V': 'ERROR', 'C': '23505', 'M': 'duplicate key value violates unique constraint "service_name_cluster_id_key"', 'D': 'Key (name, cluster_id)=(rate.delete, 1) already exists.', 's': 'public', 't': 'service', 'n': 'service_name_cluster_id_key', 'F': 'nbtinsert.c', 'L': '535', 'R': '_bt_check_unique'} [SQL: "INSERT INTO service (id, name, is_active, impl_name, is_internal, slow_threshold, cluster_id) VALUES (nextval('service_id_seq'), %s, %s, %s, %s, %s, %s), (%s, %s, %s, %s, %s, %s, %s), (%s, %s, %s, %s, %s, %s, %s), (%s, %s, %s, %s, %s, %s, %s), (%s, %s, %s, %s, %s, %s, %s)"] [parameters: ('rate.delete', True, 'rate.Delete', False, 99999, 1, 633, 'rate.create', True, 'rate.Create', False, 99999, 1, 634, 'rate.update', True, 'rate.Update', False, 99999, 1, 635, 'rate.list', True, 'rate.List', False, 99999, 1, 637, 'rate.get', True, 'rate.Get', False, 99999, 1)] (Background on this error at: http://sqlalche.me/e/gkpj)
`

The service was hot-deployed to server2 and the log file of server1 looked fine:

2019-05-02 12:37:18,354 - ^[[1;37mINFO^[[0m - 266:DummyThread-38 - zato.hot-deploy.create:0 - Creating tar archive 
2019-05-02 12:37:18,407 - ^[[1;37mINFO^[[0m - 266:DummyThread-38 - zato.hot-deploy.create:0 - Creating tar archive 
2019-05-02 12:37:19,214 - ^[[1;37mINFO^[[0m - 266:DummyThread-38 - zato.hot-deploy.create:0 - Uploaded package id:`47`, payload_name:`rate.py`

Previously I had tried the same with a different module (guest.py, also with a number of services) into server1, and the errors had appeared also in the log file of server2. I kept on trying with other modules and eventually the error appeared also in the log file of server1 (where it had been deployed).

The services appear to have reached their final destinations, though (work/hot-deploy/current/ inside
/opt/zato/env/qs-1/server1/ and /opt/zato/env/qs-1/server2/).

@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented May 2, 2019

Thanks, just to confirm it:

  • It deploys to one server but not to the other
  • rate.delete is the name of your service
  • It probably errors out on different services too, not this one alone
  • It is reproducible as long as there is more than one server

Does that sound correct?

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 2, 2019

Hi, @dsuch!

  • No, it seems to deploy to both servers (last line on my previous comment, but I added it later, sorry!)
  • rate.delete is the name of the service. Module rate has a number of services (e.g. delete, get, create, update, etc.)
  • There has been errors everytime I've deployed a module. The affected service was not always the same (e.g. booking.cancel, availability.search, etc.).
  • The second time I hot-deploy the same module with a number of services (i.e. comment a self.logger.info line, whatever), then the error does not happen. It only seems to happen the first time I deploy a module (login, guest, rate, room, booking, availability or extra).
@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented May 2, 2019

It only seems to happen the first time I deploy a module (login, guest, rate, room, booking, availability or
extra).

I see, this is the key point I think, I will try to reproduce it and let you know.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 2, 2019

Please grab anything you need from my repository if it speeds things up :-)

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 2, 2019

Also, on a different matter, I am trying to restore my previous configuration of REST channels and outgoing SQL connection:

zato enmasse /opt/zato/env/qs-1/server1 --input /opt/genesisng/config.yml --import

With no luck:

could not fetch service list
JSON parsing failed
0 warnings and 31 errors found:
+-----------------+------------------------------------------------------------------------------------------------------+
|       Key       |                                                Value                                                 |
+=================+======================================================================================================+
| err0001/E06     | Ignoring unknown element type cloud_aws_s3 in the input.                                             |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0002/E06     | Ignoring unknown element type def_amqp in the input.                                                 |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0003/E06     | Ignoring unknown element type def_cassandra in the input.                                            |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0004/E06     | Ignoring unknown element type def_cloud_openstack_swift in the input.                                |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0005/E06     | Ignoring unknown element type def_jms_wmq in the input.                                              |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0006/E06     | Ignoring unknown element type def_namespace in the input.                                            |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0007/E09     | Invalid type 'rbac_permission', must be one of '[]' (def_sec)                                        |
| invalid sec def |                                                                                                      |
| type            |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0008/E09     | Invalid type 'rbac_role', must be one of '[]' (def_sec)                                              |
| invalid sec def |                                                                                                      |
| type            |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0009/E09     | Invalid type 'rbac_permission', must be one of '[]' (def_sec)                                        |
| invalid sec def |                                                                                                      |
| type            |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0010/E09     | Invalid type 'rbac_role', must be one of '[]' (def_sec)                                              |
| invalid sec def |                                                                                                      |
| type            |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0011/E09     | Invalid type 'rbac_permission', must be one of '[]' (def_sec)                                        |
| invalid sec def |                                                                                                      |
| type            |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0012/E09     | Invalid type 'basic_auth', must be one of '[]' (def_sec)                                             |
| invalid sec def |                                                                                                      |
| type            |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0013/E09     | Invalid type 'rbac_permission', must be one of '[]' (def_sec)                                        |
| invalid sec def |                                                                                                      |
| type            |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0014/E06     | Ignoring unknown element type email_imap in the input.                                               |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0015/E06     | Ignoring unknown element type email_smtp in the input.                                               |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0016/E06     | Ignoring unknown element type json_pointer in the input.                                             |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0017/E06     | Ignoring unknown element type notif_cloud_openstack_swift in the input.                              |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0018/E06     | Ignoring unknown element type outconn_ftp in the input.                                              |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0019/E06     | Ignoring unknown element type outconn_odoo in the input.                                             |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0020/E06     | Ignoring unknown element type outconn_sap in the input.                                              |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0021/E06     | Ignoring unknown element type outconn_sql in the input.                                              |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0022/E06     | Ignoring unknown element type outconn_stomp in the input.                                            |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0023/E06     | Ignoring unknown element type outconn_zmq in the input.                                              |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0024/E06     | Ignoring unknown element type pubsub_topic in the input.                                             |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0025/E06     | Ignoring unknown element type search_es in the input.                                                |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0026/E06     | Ignoring unknown element type search_solr in the input.                                              |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0027/E06     | Ignoring unknown element type xpath in the input.                                                    |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0028/E06     | Ignoring unknown element type zato_cache_builtin in the input.                                       |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0029/E06     | Ignoring unknown element type zato_cache_memcached in the input.                                     |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0030/E06     | Ignoring unknown element type zato_generic_connection in the input.                                  |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+
| err0031/E06     | Ignoring unknown element type zato_sms_twilio in the input.                                          |
| unrecognized    |                                                                                                      |
| import element  |                                                                                                      |
+-----------------+------------------------------------------------------------------------------------------------------+

I tried adding --dump-format yaml but the error persisted. Used to work before, with 3.0. Not sure if format autodetection is not working properly or whether there is a new paramter that does not yet show when using zato enmasse --help.

P.S. Please let me know if you'd rather have me open separate issues on this "testing my prototype application with Zato 3.1 and Python 3" adventure, as this issue may end up being the mother of all dark holes :-)

@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented May 2, 2019

Let's keep it in one ticket for now but I just do not know using which release you created the enmasse file? I think it was at least 3.0 because it is a YAML one?

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 2, 2019

Yes, it was created using Zato 3.0 with --dump-format yaml on my old installation. This is the configuration file, by the way.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 3, 2019

Another different matter, I was using the package enum34 in the prototype application and I am trying to get rid of it when migrating to Python 3. So I've removed the dependency from my setup.py file and my requirements.txt file. And I've turned these two lines:

from sqlalchemy import Enum
import enum

Into the following:

from sqlalchemy import Enum as sqlEnum
from enum import Enum as pyEnum

Strangely, I was not getting any errors before, and I was not getting any errors after. Then I realised it's also a dependency of Zato, as per its requirements.txt file. What are your plans on this topic, @dsuch? Zato 3.1 will only be Python 3 compatible, thus you'd remove the dependency? Or you want it to be 2 and 3 compatible, thus you'll keep it?

Thanks.

@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented May 3, 2019

Hello,

both Python 2.7 and 3 will be supported in Zato 3.1+ and there are no plans to drop support for Python 2.7 any time soon.

The dependencies are in:

  • requirements.txt - common ones
  • _req_py27.txt - things specific to Python 2.7
  • _req_py3.txt - ditto for Python 3

As for enums - I do not have any plans to remove the dependency on enum34 for now. But if you need it in your code, I would recommend adding an explicit dependency on it just to be sure it will continue to work regardless of Zato's own.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 3, 2019

So, if enum34 is inside requirements.txt, it would mean it's both required when using Python 2.7 and Python 3. Is it because Python 3 includes also versions < 3.4?

I ask this because, if I am not mistaken, it's not required from 3.4 onwards. Ubuntu 18.04, for instance, includes Python 3.6. It may also be that such package has implemented the necessary mechanisms to disable itself if the version of Python is 3.4 or greater...

@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented May 4, 2019

Thanks, I compared Python 3's enum with enum34 and I moved the latter to Python2.7-only dependencies.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 5, 2019

Hi again! Just updated the source code using ./update.sh inside zato/code/ and found that both servers were not starting. So I run them in the foreground in verbose mode and this is what I got:

$ zato start /opt/zato/env/qs-1/server1/ --sync-internal --verbose --fg
Stderr received from program `/opt/zato/zato/code/bin/py -m zato.server.main /opt/zato/env/qs-1/server1 fg=TrueZATO_ZATO_ZATOsync_internal=TrueZATO_ZATO_ZATOsecret_key=  2> /tmp/tmp7dghut69-zato-start-server.txt` e:`Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/opt/zato/zato/code/zato-server/src/zato/server/main.py", line 65, in <module>
    from zato.server.base.parallel import ParallelServer
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/parallel/__init__.py", line 54, in <module>
    from zato.server.base.worker import WorkerStore
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 66, in <module>
    from zato.server.connection.http_soap.channel import RequestDispatcher, RequestHandler
  File "/opt/zato/zato/code/zato-server/src/zato/server/connection/http_soap/channel.py", line 48, in <module>
    from stackprinter import format as stack_format
ModuleNotFoundError: No module named 'stackprinter'
`, kw:`{'async': False}`

I checked the *.txt files and found the stackprinter module:

~/zato/code$ grep stackprinter *.txt
_req_py3.txt:stackprinter==0.2.0

For some reason it did not get installed upon execution of the ./update.sh. I installed it manually and a new problem appeared:

$ zato start /opt/zato/env/qs-1/server1/ --sync-internal --verbose --fg
Stderr received from program `/opt/zato/zato/code/bin/py -m zato.server.main /opt/zato/env/qs-1/server1 fg=TrueZATO_ZATO_ZATOsync_internal=TrueZATO_ZATO_ZATOsecret_key=  2> /tmp/tmpyhyf18l5-zato-start-server.txt` e:`Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/opt/zato/zato/code/zato-server/src/zato/server/main.py", line 65, in <module>
    from zato.server.base.parallel import ParallelServer
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/parallel/__init__.py", line 54, in <module>
    from zato.server.base.worker import WorkerStore
  File "/opt/zato/zato/code/zato-server/src/zato/server/base/worker/__init__.py", line 79, in <module>
    from zato.server.ext.zunicorn.workers.ggevent import GeventWorker as GunicornGeventWorker
  File "/opt/zato/zato/code/zato-server/src/zato/server/ext/zunicorn/workers/ggevent.py", line 60, in <module>
    from zato.server.ext.zunicorn.http.wsgi import base_environ
  File "/opt/zato/zato/code/zato-server/src/zato/server/ext/zunicorn/http/__init__.py", line 37, in <module>
    from zato.server.ext.zunicorn.http.message import Message, Request
  File "/opt/zato/zato/code/zato-server/src/zato/server/ext/zunicorn/http/message.py", line 41, in <module>
    from zato.server.ext.zunicorn._compat import bytes_to_str
  File "/opt/zato/zato/code/zato-server/src/zato/server/ext/zunicorn/_compat.py", line 39, in <module>
    from zato.server.ext.zunicorn import six
  File "/opt/zato/zato/code/zato-server/src/zato/server/ext/zunicorn/six.py", line 75, in <module>
    from past.builtins import basestring, execfile, file, long, unicode
ImportError: cannot import name 'file'
`, kw:`{'async': False}`

I'd say the affected package would be this, correct?

past (0.11.1) - [Experimental] Run Python 2 code from Python 3

I could not find it in the requirements files. I tried installing it manually, but I couldn't:

$ pip install past
Collecting past
  ERROR: Could not find a version that satisfies the requirement past (from versions: none)
ERROR: No matching distribution found for past

So I checked the package's page on PyPi and found that you are supposed to install the future package, which is already installed and listed in the requirements.txt file:

~/zato/code$ grep future *.txt
requirements.txt:future==0.17.1
requirements.txt:futures==2.1.6

Incidentally, would the futures package happen to fall into the same category as enum34 in terms of its location inside the requirements files?

$ pip show futures
Name: futures
Version: 2.1.6
Summary: Backport of the concurrent.futures package from Python 3.2
Home-page: http://code.google.com/p/pythonfutures
Author: Alex Gronholm
Author-email: alex.gronholm+pypi@nextday.fi
License: BSD
Location: /opt/zato/zato/code/lib/python3.6/site-packages
Requires: 
Required-by:

Moreover, this led me to the following question: if you plan on your application to be supported on Python 3.6+ only, you wouldn't require all your files to begin with the following lines, would you?

from __future__ import absolute_import, division
from __future__ import print_function, unicode_literals
@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 6, 2019

Regarding the last topic on my previous comment about the future imports, I found this Future statement definitions page on Python's official documentation.

After reading it, my conclusion would be that, if you are using Python 3.6 on an Ubuntu 18.04, as I am, these imports are not required anymore as they are all four mandatory starting in Python version 3.0:

from __future__ import absolute_import, division
from __future__ import print_function, unicode_literals

So it would be correct to remove them from an application using Zato 3.0 that expects to be compatible with Python 3.0+ only, wouldn't it?

@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented May 6, 2019

So it would be correct to remove them from an application using Zato 3.0 that expects to be compatible
with Python 3.0+ only, wouldn't it?

This is correct with Zato 3.1 onwards but Zato 3.0 and earlier are Python 2.7-only and the imports are required.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 7, 2019

Yes, sorry, I meant with Zato 3.1. An application that expects to work under Zato 3.1 and such application have Python 3.0+ as requirement.

By the way, will Zato 3.1 be compatible with Python 2.7 or will it require Python 3.0?

@dsuch

This comment has been minimized.

Copy link
Collaborator Author

commented May 7, 2019

Zato 3.1 will support both Python 2.7 and Python 3 for years to come - RHEL and Ubuntu have LTS releases with Python 2.7 and this will be probably the main driving factor.

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 7, 2019

Good point, you're right! 👍

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 7, 2019

I found an issue with the caches and opened a different issue #953, as its content was too much for yet another comment here, IMHO:

@jsabater

This comment has been minimized.

Copy link
Contributor

commented May 7, 2019

I found another issue when playing with the caches as per the previous comment which I think has nothing to do with it, so I've opened yet another issue #954.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.