Fri, 10 Mar 2017 18:23:29 +0100 [repo] Drop Session at last
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 18:23:29 +0100] rev 12047
[repo] Drop Session at last This is not used at all anymore.
Fri, 10 Mar 2017 18:21:22 +0100 Fix flake8 some errors
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 18:21:22 +0100] rev 12046
Fix flake8 some errors
Fri, 10 Mar 2017 18:18:51 +0100 [test] Use existing reference to repo_source
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 18:18:51 +0100] rev 12045
[test] Use existing reference to repo_source
Fri, 10 Mar 2017 18:04:25 +0100 [repo] Drop repo.new_session method
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 18:04:25 +0100] rev 12044
[repo] Drop repo.new_session method we should not go through Session to create Connection anymore. This is unofficial API, no backward compat for now.
Tue, 14 Mar 2017 11:07:58 +0100 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr> [Tue, 14 Mar 2017 11:07:58 +0100] rev 12043
Stop using Session on the repository side Only expect session on web request, and let the web session/authentication managers provide them. Access to cnx.data, which used to return session data, is deprecated: there is no more access to session data from the repository side, and they should be access from req.session.data from the web side.
Fri, 10 Mar 2017 18:00:13 +0100 [test] Drop unnecessary call to new_session
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 18:00:13 +0100] rev 12042
[test] Drop unnecessary call to new_session This is not unittest, the above call is enough.
Fri, 10 Mar 2017 17:58:25 +0100 [user] Drop ugly hack on CWUser entity class
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 17:58:25 +0100] rev 12041
[user] Drop ugly hack on CWUser entity class which should be not necessary anymore, beside two remaining usage in our own test suite.
Fri, 10 Mar 2017 17:57:13 +0100 [test] Use user_session_cache_key function
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 17:57:13 +0100] rev 12040
[test] Use user_session_cache_key function to generate cache key.
Fri, 10 Mar 2017 17:52:44 +0100 [session+test] Stop storing / accessing session when it's not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 17:52:44 +0100] rev 12039
[session+test] Stop storing / accessing session when it's not necessary
Fri, 10 Mar 2017 17:46:06 +0100 [devtools] Stop relying on Session to create connection in RepoAccess
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 17:46:06 +0100] rev 12038
[devtools] Stop relying on Session to create connection in RepoAccess
Fri, 10 Mar 2017 17:44:03 +0100 [devtools] Stop using repo.new_session
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 17:44:03 +0100] rev 12037
[devtools] Stop using repo.new_session
Fri, 10 Mar 2017 18:25:35 +0100 [session] Kill support for a 'session_open' hook event
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 18:25:35 +0100] rev 12036
[session] Kill support for a 'session_open' hook event To be consistent with dropping of the 'session_close' event, and also because this is already not called when using pyramid.
Fri, 10 Mar 2017 17:03:28 +0100 [devtools] Rename FakeSession into FakeConnection
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 17:03:28 +0100] rev 12035
[devtools] Rename FakeSession into FakeConnection because it is what it is.
Fri, 10 Mar 2017 16:55:57 +0100 [cleanup] Drop references to the old internal_session method
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 16:55:57 +0100] rev 12034
[cleanup] Drop references to the old internal_session method dropped a while ago, no need to talk about it in a docstring nor to fake it.
Fri, 10 Mar 2017 16:31:08 +0100 [session] Drop unused class
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 16:31:08 +0100] rev 12033
[session] Drop unused class
Fri, 10 Mar 2017 16:14:05 +0100 [cleanup] Drop no more used parse_repo_uri function
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 16:14:05 +0100] rev 12032
[cleanup] Drop no more used parse_repo_uri function
Fri, 10 Mar 2017 14:07:15 +0100 [server] Fix flake8 error of test/data/hooks.py
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 14:07:15 +0100] rev 12031
[server] Fix flake8 error of test/data/hooks.py
Fri, 10 Mar 2017 14:02:31 +0100 [repo] Drop repo.connect backward compat
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 14:02:31 +0100] rev 12030
[repo] Drop repo.connect backward compat use new_session instead (introduced in 3.19 iirc)
Fri, 10 Mar 2017 14:01:45 +0100 [session] Drop no more necessary Session.sessionid and Connection.connectionid
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 14:01:45 +0100] rev 12029
[session] Drop no more necessary Session.sessionid and Connection.connectionid
Fri, 10 Mar 2017 14:04:26 +0100 [repo] Kill repo._sessions
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 14:04:26 +0100] rev 12028
[repo] Kill repo._sessions and with it the need to have a looping task to clean it up, and with that all the session's timestamping machinery.
Fri, 10 Mar 2017 18:24:40 +0100 [repo] Stop closing session
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 18:24:40 +0100] rev 12027
[repo] Stop closing session The only point in "closing" session is to call the `session_close` event. Since I'm not aware of any application relying on it, I think this is too costly (in term of code) to maintain and propose to drop it.
Fri, 10 Mar 2017 12:07:29 +0100 [views] Stop giving stats / debug information relying on _sessions
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 12:07:29 +0100] rev 12026
[views] Stop giving stats / debug information relying on _sessions This is already broken when using pyramid anyway.
Fri, 10 Mar 2017 16:41:10 +0100 [session] Stop relying on _sessions to synchronize living session
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 16:41:10 +0100] rev 12025
[session] Stop relying on _sessions to synchronize living session by doing what we currently do in pyramid. Also, attempt to synchronize CWUser's class sounds like a dark corner case handling that should be removed in favor of short lived user objects (beside it shouldn't occur except during migration).
Fri, 10 Mar 2017 12:01:31 +0100 [test] Drop useless access to repo._sessions
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 12:01:31 +0100] rev 12024
[test] Drop useless access to repo._sessions test still succeed afterwards.
Fri, 10 Mar 2017 11:27:01 +0100 [repo] Fix flake8 errors in server/__init__.py
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 11:27:01 +0100] rev 12023
[repo] Fix flake8 errors in server/__init__.py
Fri, 10 Mar 2017 11:25:24 +0100 [repo] Drop no more used ShuttingDown exception
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 11:25:24 +0100] rev 12022
[repo] Drop no more used ShuttingDown exception
Fri, 10 Mar 2017 11:55:16 +0100 [repo] Drop _get_session method
Sylvain Thénault <sylvain.thenault@logilab.fr> [Fri, 10 Mar 2017 11:55:16 +0100] rev 12021
[repo] Drop _get_session method it's not actually necessary but holds underlying _sessions dict handling. Drop backward compat relying on it (which IMO should not be a problem). Drop import of unused QueryError along the way.
Thu, 09 Mar 2017 18:02:16 +0100 [test] Drop call to CubicWebConfiguration.load_cwctl_plugins in unittest_cwctl.py
Denis Laxalde <denis.laxalde@logilab.fr> [Thu, 09 Mar 2017 18:02:16 +0100] rev 12020
[test] Drop call to CubicWebConfiguration.load_cwctl_plugins in unittest_cwctl.py This is no longer need now that we call load_available_configurations() in the "list" command (see 5e7282bdf140).
Thu, 09 Mar 2017 16:35:58 +0100 [web] Extract a base class out WebConfiguration
Denis Laxalde <denis.laxalde@logilab.fr> [Thu, 09 Mar 2017 16:35:58 +0100] rev 12019
[web] Extract a base class out WebConfiguration This will be used to build a CubicWebPyramidConfiguration in following changeset.
Thu, 09 Mar 2017 16:41:18 +0100 [tox] Drop reference to removed init_instance.py file in flake8-ok-files.txt
Denis Laxalde <denis.laxalde@logilab.fr> [Thu, 09 Mar 2017 16:41:18 +0100] rev 12018
[tox] Drop reference to removed init_instance.py file in flake8-ok-files.txt The file got removed in 1b9fd8bda1cd.
Fri, 10 Mar 2017 09:39:18 +0100 [web] Put 'use-uicache' option in level 2
Denis Laxalde <denis.laxalde@logilab.fr> [Fri, 10 Mar 2017 09:39:18 +0100] rev 12017
[web] Put 'use-uicache' option in level 2 So that users do not get prompted with this. Follow-up on c34590161082.
Tue, 21 Feb 2017 08:56:38 +0100 [server] Add a "scheduler" command to run repository scheduler
Denis Laxalde <denis.laxalde@logilab.fr> [Tue, 21 Feb 2017 08:56:38 +0100] rev 12016
[server] Add a "scheduler" command to run repository scheduler This commands starts the repository scheduler as a standalone process that should complement a CubicWeb web instance running as a WSGI application. Added a log message in repository's shutdown method to help testing the command (i.e. make sure the method is called after the scheduler stopped). Related to #17057223.
Mon, 06 Mar 2017 15:13:44 +0100 [cwconfig] Do not instantiate a repo with a scheduler in repository method
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 15:13:44 +0100] rev 12015
[cwconfig] Do not instantiate a repo with a scheduler in repository method None of the caller of this method need the repository to have a scheduler and having a scheduler should be something that's explicitly requested.
Mon, 06 Mar 2017 14:50:00 +0100 [server] Make cubicweb/server/utils.py flake8-clean
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 14:50:00 +0100] rev 12014
[server] Make cubicweb/server/utils.py flake8-clean
Mon, 06 Mar 2017 14:38:52 +0100 [server] Drop utils's LoopTask and TasksManager classes not used anymore
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 14:38:52 +0100] rev 12013
[server] Drop utils's LoopTask and TasksManager classes not used anymore Related to 17057223.
Mon, 06 Mar 2017 13:23:33 +0100 [server] replace repository's tasks manager by a scheduler
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 13:23:33 +0100] rev 12012
[server] replace repository's tasks manager by a scheduler Repository() does not accept anymore a 'tasks_manager' argument but rather a 'scheduler' argument which is expected to be an instance of sched.scheduler class. The drop the _tasks_manager attribute of the repository and adjust all internal usages of it. In particular, in the 'repo_stats' service we do not export 'looping_tasks' statistics anymore as there's no way to retrieve this anymore from a web instance. Closes #17057223.
Mon, 06 Mar 2017 13:21:50 +0100 [server] introduce a scheduler class to run repository "looping tasks"
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 13:21:50 +0100] rev 12011
[server] introduce a scheduler class to run repository "looping tasks" We just use the sched module from the standard library and introduce a tiny Python2/3 compatibility layer (more for convenience actually). The "looping" aspect of tasks (previously in LoopTask class) is re-implemeted as a `schedule_periodic_task` function. This is a reasonably thin layer as compared to LoopTask/TasksManager classes. Only the "restart" aspect of LoopTask is no longer present as I'm not sure it's worth keeping. The advantage of using this (in addition to eventually dropping our custom code) is that this scheduler class provides a `run` method that blocks the process while running tasks in its queue. So we can rely on this to have a 'scheduler' ctl command (see forthcoming patch) that would only run "looping tasks" without having to implement the "blocking" aspect ourself. Related to #17057223.
Thu, 16 Feb 2017 11:15:23 +0100 web: add options to ignore css compilation and uicache
Samuel Trégouët <samuel.tregouet@logilab.fr> [Thu, 16 Feb 2017 11:15:23 +0100] rev 12010
web: add options to ignore css compilation and uicache
Thu, 16 Feb 2017 10:56:45 +0100 [skeleton] call includeme from new cube
Samuel Trégouët <samuel.tregouet@logilab.fr> [Thu, 16 Feb 2017 10:56:45 +0100] rev 12009
[skeleton] call includeme from new cube
Mon, 06 Mar 2017 14:19:20 +0100 [etwist] Do not call repository's start_looping_tasks anymore and warn about this
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 14:19:20 +0100] rev 12008
[etwist] Do not call repository's start_looping_tasks anymore and warn about this We are about to drop this method from Repository class and replace it by a blocking alternative. This is not compatible with how things currently work in a Twisted server implementation. So do not start repository "looping tasks" in Twisted server anymore and issue a warning about this. If someone is interested in restoring the "all-in-one" behavior where the repository runs within a Twisted server, they may start by implementing repository looping tasks using a Twisted mechanism such as, e.g., http://twistedmatrix.com/documents/current/core/howto/time.html and eventually provide the repository with a compatible scheduler instance so that is can register its periodic tasks. At the moment, we lack resources to do this (and maintain the Twisted server of CubicWeb in general). Related to #17057223.
Thu, 09 Mar 2017 09:16:00 +0100 [test] Flake8-clean and use stdlib unittest in cubicweb/server/test/unittest_utils.py
Denis Laxalde <denis.laxalde@logilab.fr> [Thu, 09 Mar 2017 09:16:00 +0100] rev 12007
[test] Flake8-clean and use stdlib unittest in cubicweb/server/test/unittest_utils.py
Tue, 07 Mar 2017 12:08:39 +0100 [web] Don't raise ProcessFormError if there is no value specified
Sylvain Thénault <sylvain.thenault@logilab.fr> [Tue, 07 Mar 2017 12:08:39 +0100] rev 12006
[web] Don't raise ProcessFormError if there is no value specified a03376213747 introduced a slight modification in None / empty string values and with it a regression where an exception is raised on empty values, while we should simply consider no value is specified and return None.
Tue, 07 Mar 2017 11:59:07 +0100 [test] Cleanup imports in unittest_form
Sylvain Thénault <sylvain.thenault@logilab.fr> [Tue, 07 Mar 2017 11:59:07 +0100] rev 12005
[test] Cleanup imports in unittest_form Remove unused and reorder, + use bare unittest along the way.
Tue, 07 Mar 2017 14:27:09 +0100 Fix log level parameter not taken into account in cwsource log table 3.23
Florent Cayré <florent.cayre@logilab.fr> [Tue, 07 Mar 2017 14:27:09 +0100] rev 12004
Fix log level parameter not taken into account in cwsource log table An error in the jquery selector of the html widget controlling the log level was the cause of this bug. Closes #15772634 (grafted from c9129aae884b476455c8ed1ad802efc3a26503a5)
Mon, 06 Mar 2017 13:49:51 +0100 [pyramid] Drop call to repository's start_looping_tasks method and warn about this
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 13:49:51 +0100] rev 12003
[pyramid] Drop call to repository's start_looping_tasks method and warn about this We are about to drop the start_looping_tasks method and running "looping tasks" along the WSGI application is not a very good idea. So issue a warning pointing to the forthcoming "scheduler" command. Related to #17057223.
Mon, 06 Mar 2017 15:22:16 +0100 [test] Make unittest_serverctl.py flake8-clean
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 15:22:16 +0100] rev 12002
[test] Make unittest_serverctl.py flake8-clean
Mon, 06 Mar 2017 13:15:51 +0100 [wsgi] Drop calls to repo.start_looping_tasks
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 13:15:51 +0100] rev 12001
[wsgi] Drop calls to repo.start_looping_tasks It's unlikely that these implementations were ever used so we do not bother with deprecation or a warning. We just drop the call to this method which should not be called from within a WSGI application. Related to #17057223.
Mon, 06 Mar 2017 15:16:53 +0100 [pyramid] Drop useless "init_instance" module
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 15:16:53 +0100] rev 12000
[pyramid] Drop useless "init_instance" module
Mon, 06 Mar 2017 15:01:41 +0100 [server] Drop inexistent "bootstrap" argument in Repository initialization
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 06 Mar 2017 15:01:41 +0100] rev 11999
[server] Drop inexistent "bootstrap" argument in Repository initialization This is a missing bit from 5de78b6fff2e. Unfortunately this code appears to be uncovered by our test suite.
Wed, 08 Feb 2017 16:05:00 +0100 [server] fix a typo in a docstring
David Douard <david.douard@logilab.fr> [Wed, 08 Feb 2017 16:05:00 +0100] rev 11998
[server] fix a typo in a docstring
Fri, 24 Feb 2017 09:18:08 +0100 [ctl] Load available configurations in "cubicweb-ctl list" 3.24
Denis Laxalde <denis.laxalde@logilab.fr> [Fri, 24 Feb 2017 09:18:08 +0100] rev 11997
[ctl] Load available configurations in "cubicweb-ctl list" Otherwise we rely on associated ctl plugins to be loaded which is arguably orthogonal to configurations.
Thu, 23 Feb 2017 10:59:56 +0100 [web/views] Fix a docstring
Sylvain Thénault <sylvain.thenault@logilab.fr> [Thu, 23 Feb 2017 10:59:56 +0100] rev 11996
[web/views] Fix a docstring
Thu, 23 Feb 2017 08:37:39 +0100 [server] Use looping_task method in Repository._prepare_startup()
Denis Laxalde <denis.laxalde@logilab.fr> [Thu, 23 Feb 2017 08:37:39 +0100] rev 11995
[server] Use looping_task method in Repository._prepare_startup()
Mon, 27 Feb 2017 17:13:45 +0100 [skeleton] Drop logging configuration from development.ini
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 27 Feb 2017 17:13:45 +0100] rev 11994
[skeleton] Drop logging configuration from development.ini This is actually not useful as logging is already initialized and configure "somewhere else" where the repository is started.
Mon, 27 Feb 2017 14:49:32 +0100 [pyramid] Drop retrieval of auth/session secret in all-in-one.conf
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 27 Feb 2017 14:49:32 +0100] rev 11993
[pyramid] Drop retrieval of auth/session secret in all-in-one.conf We actually never supported this in cubicweb, but only in pyramid-cubicweb.
Mon, 27 Feb 2017 09:06:23 +0100 [cwctl] Recommend 'pyramid' before 'wsgi' when twisted is not available
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 27 Feb 2017 09:06:23 +0100] rev 11992
[cwctl] Recommend 'pyramid' before 'wsgi' when twisted is not available Not sure anyone ever really used the latter and the former is certainly more reliable/tested.
Mon, 27 Feb 2017 09:05:33 +0100 [cwctl] Drop message about 'the pyramid cube' in "start" command
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 27 Feb 2017 09:05:33 +0100] rev 11991
[cwctl] Drop message about 'the pyramid cube' in "start" command This is shown when twisted is not importable and we suggest to use 'cubicweb pyramid <appid>' instead. Since 3.24, cubicweb-pyramid got merge in cubicweb so drop this reference in the message.
Mon, 27 Feb 2017 16:57:59 +0100 [cwconfig] Fix two NameError in load_available_configs()
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 27 Feb 2017 16:57:59 +0100] rev 11990
[cwconfig] Fix two NameError in load_available_configs() This comes from a copy-paste in d92d75b17a85.
Mon, 27 Feb 2017 08:53:52 +0100 [etwist] Drop try/except around definitions of 'all-in-one' configuration and command handlers
Denis Laxalde <denis.laxalde@logilab.fr> [Mon, 27 Feb 2017 08:53:52 +0100] rev 11989
[etwist] Drop try/except around definitions of 'all-in-one' configuration and command handlers cubicweb.server is no longer conditionally shipped, neither in python package nor in debian package since 3.24.
Tue, 28 Feb 2017 16:55:32 +0100 [server] Call 'server_startup' hooks at the end of repository "bootstrap"
Denis Laxalde <denis.laxalde@logilab.fr> [Tue, 28 Feb 2017 16:55:32 +0100] rev 11988
[server] Call 'server_startup' hooks at the end of repository "bootstrap" Now that we have guarded all calls to Repository.looping_task() in 'server_startup' hooks we can execute this hooks category at bootstrap step. This way, repositories running without a tasks manager (i.e. those embedded into a WSGI application) will have these hooks triggered.
Tue, 28 Feb 2017 16:46:16 +0100 [pyramid] Drop module-level cache and cleanup looping tasks in tools
Denis Laxalde <denis.laxalde@logilab.fr> [Tue, 28 Feb 2017 16:46:16 +0100] rev 11987
[pyramid] Drop module-level cache and cleanup looping tasks in tools And use a LRU cache over cached_build_user function. This looping task is problematic because it would not be run from within a WSGI application which does not have a repository with a tasks manager. This pulls an explicit dependency on 'repoze.lru' but it's not a big deal since pyramid already depends on this. RPM spec file not update since it does not even mention pyramid...
Tue, 28 Feb 2017 16:11:17 +0100 [hooks] Return early in server_startup hooks if the repository has not tasks manager
Denis Laxalde <denis.laxalde@logilab.fr> [Tue, 28 Feb 2017 16:11:17 +0100] rev 11986
[hooks] Return early in server_startup hooks if the repository has not tasks manager
Tue, 28 Feb 2017 16:05:00 +0100 [server] Only register "clean_sessions" looping tasks if repository has a tasks manager
Denis Laxalde <denis.laxalde@logilab.fr> [Tue, 28 Feb 2017 16:05:00 +0100] rev 11985
[server] Only register "clean_sessions" looping tasks if repository has a tasks manager This prepares for calling Repository's _prepare_startup() in bootstrap() so that repository instances without a tasks manager running can still have their 'server_startup' hooks triggered (this is particularly useful for BFSS storages).
Fri, 24 Feb 2017 10:16:17 +0100 [utils] Do not pass a tasks manager to Repository in admincnx()
Denis Laxalde <denis.laxalde@logilab.fr> [Fri, 24 Feb 2017 10:16:17 +0100] rev 11984
[utils] Do not pass a tasks manager to Repository in admincnx() We do not call repo.start_looping_tasks() for the instantiated repository, so a tasks manager is useless.
(0) -10000 -3000 -1000 -300 -100 -64 +64 +100 +300 tip