# Buggy code
def expire(self, key, ttl):
    self._ttl[self.prefix + key] = utils.msec_time() + int(ttl * 1000.0)


# Traceback (RuntimeError)
2016-08-16 14:57:02,332 ERROR [kinto.core.views.errors][waitress] "POST  /v1/buckets/e3e5dfdd-b5de-e9dd-e2ad-637fc2c6481f/collections/tickets/records" ? (? ms) dictionary changed size during iteration agent=None authn_type=basicauth collection_id=record collection_timestamp=1471359417323 errno=None exception=Traceback (most recent call last):
File "/code/kinto/core/utils.py", line 322, in follow_subrequest
return request.invoke_subrequest(subrequest, **kwargs), subrequest
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 211, in invoke_subrequest
response = handle_request(request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 158, in handle_request
view_name
File "/usr/local/lib/python3.5/dist-packages/pyramid/view.py", line 547, in _call_view
response = view_callable(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 413, in viewresult_to_response
result = view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 147, in _requestonly_view
response = view(request)
File "/code/kinto/plugins/default_bucket/__init__.py", line 159, in default_bucket
response = request.invoke_subrequest(subrequest)
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 211, in invoke_subrequest
response = handle_request(request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 158, in handle_request
view_name
File "/usr/local/lib/python3.5/dist-packages/pyramid/view.py", line 547, in _call_view
response = view_callable(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/config/views.py", line 182, in __call__
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 393, in attr_view
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 371, in predicate_wrapper
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 302, in _secured_view
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 442, in rendered_view
result = view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 147, in _requestonly_view
response = view(request)
File "/usr/local/lib/python3.5/dist-packages/cornice/service.py", line 571, in wrapper
response = view_()
File "/code/kinto/core/resource/__init__.py", line 311, in collection_post
existing = self._get_record_or_404(_id)
File "/code/kinto/core/resource/__init__.py", line 681, in _get_record_or_404
return self.model.get_record(record_id)
File "/code/kinto/core/resource/model.py", line 276, in get_record
permissions = self.permission.get_object_permissions(perm_object_id)
File "/code/kinto/core/permission/__init__.py", line 136, in get_object_permissions
perms = self.get_objects_permissions([object_id], permissions)
File "/code/kinto/core/permission/memory.py", line 114, in get_objects_permissions
aces = [k for k in self._store.keys()
File "/code/kinto/core/permission/memory.py", line 114, in <listcomp>
aces = [k for k in self._store.keys()
RuntimeError: dictionary changed size during iteration lang=None uid=84ffd9ad5044b2b77b40e0f96fee3112f02894fcbe0eec6dfb8008394955ab7f
2016-08-16 14:57:02,351 INFO  [kinto.core.views.batch][waitress] "POST  /v1/buckets/e3e5dfdd-b5de-e9dd-e2ad-637fc2c6481f/collections/tickets/records" 200 (22 ms) subrequest.summary agent=None authn_type=basicauth collection_id=record collection_timestamp=1471359422318 errno=None lang=None time=2016-08-16T14:57:02.351000 uid=84ffd9ad5044b2b77b40e0f96fee3112f02894fcbe0eec6dfb8008394955ab7f
2016-08-16 14:57:02,376 INFO  [kinto.core.views.batch][waitress] "POST  /v1/buckets/e3e5dfdd-b5de-e9dd-e2ad-637fc2c6481f/collections/tickets/records" 201 (33 ms) subrequest.summary agent=None authn_type=basicauth collection_id=record collection_timestamp=1471359422318 errno=110 lang=None time=2016-08-16T14:57:02.376000 uid=84ffd9ad5044b2b77b40e0f96fee3112f02894fcbe0eec6dfb8008394955ab7f
2016-08-16 14:57:02,381 INFO  [kinto.core.views.batch][waitress] "POST  /v1/buckets/e3e5dfdd-b5de-e9dd-e2ad-637fc2c6481f/collections/tickets/records" 200 (30 ms) subrequest.summary agent=None authn_type=basicauth collection_id=record collection_timestamp=1471359422318 errno=None lang=None time=2016-08-16T14:57:02.381000 uid=84ffd9ad5044b2b77b40e0f96fee3112f02894fcbe0eec6dfb8008394955ab7f
2016-08-16 14:57:02,381 ERROR [kinto.core.views.errors][waitress] "POST  /v1/buckets/e3e5dfdd-b5de-e9dd-e2ad-637fc2c6481f/collections/tickets/records" ? (? ms) dictionary changed size during iteration agent=None authn_type=basicauth collection_id=record collection_timestamp=1471359417323 errno=999 exception=Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/pyramid/tweens.py", line 22, in excview_tween
response = handler(request)
File "/usr/local/lib/python3.5/dist-packages/pyramid_tm/__init__.py", line 101, in tm_tween
reraise(*exc_info)
File "/usr/local/lib/python3.5/dist-packages/pyramid_tm/compat.py", line 15, in reraise
raise value
File "/usr/local/lib/python3.5/dist-packages/pyramid_tm/__init__.py", line 83, in tm_tween
response = handler(request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 158, in handle_request
view_name
File "/usr/local/lib/python3.5/dist-packages/pyramid/view.py", line 547, in _call_view
response = view_callable(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/config/views.py", line 182, in __call__
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 393, in attr_view
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 371, in predicate_wrapper
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 442, in rendered_view
result = view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 147, in _requestonly_view
response = view(request)
File "/usr/local/lib/python3.5/dist-packages/cornice/service.py", line 573, in wrapper
response = view_(request)
File "/code/kinto/core/views/batch.py", line 100, in post_batch
use_tweens=False)
File "/code/kinto/core/utils.py", line 326, in follow_subrequest
raise e
File "/code/kinto/core/utils.py", line 322, in follow_subrequest
return request.invoke_subrequest(subrequest, **kwargs), subrequest
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 211, in invoke_subrequest
response = handle_request(request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 158, in handle_request
view_name
File "/usr/local/lib/python3.5/dist-packages/pyramid/view.py", line 547, in _call_view
response = view_callable(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 413, in viewresult_to_response
result = view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 147, in _requestonly_view
response = view(request)
File "/code/kinto/plugins/default_bucket/__init__.py", line 159, in default_bucket
response = request.invoke_subrequest(subrequest)
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 211, in invoke_subrequest
response = handle_request(request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/router.py", line 158, in handle_request
view_name
File "/usr/local/lib/python3.5/dist-packages/pyramid/view.py", line 547, in _call_view
response = view_callable(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/config/views.py", line 182, in __call__
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 393, in attr_view
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 371, in predicate_wrapper
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 302, in _secured_view
return view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 442, in rendered_view
result = view(context, request)
File "/usr/local/lib/python3.5/dist-packages/pyramid/viewderivers.py", line 147, in _requestonly_view
response = view(request)
File "/usr/local/lib/python3.5/dist-packages/cornice/service.py", line 571, in wrapper
response = view_()
File "/code/kinto/core/resource/__init__.py", line 311, in collection_post
existing = self._get_record_or_404(_id)
File "/code/kinto/core/resource/__init__.py", line 681, in _get_record_or_404
return self.model.get_record(record_id)
File "/code/kinto/core/resource/model.py", line 276, in get_record
permissions = self.permission.get_object_permissions(perm_object_id)
File "/code/kinto/core/permission/__init__.py", line 136, in get_object_permissions
perms = self.get_objects_permissions([object_id], permissions)
File "/code/kinto/core/permission/memory.py", line 114, in get_objects_permissions
aces = [k for k in self._store.keys()
File "/code/kinto/core/permission/memory.py", line 114, in <listcomp>
aces = [k for k in self._store.keys()
RuntimeError: dictionary changed size during iteration lang=None uid=84ffd9ad5044b2b77b40e0f96fee3112f02894fcbe0eec6dfb8008394955ab7f

# Fixed code
def expire(self, key, ttl):
    self._ttl[self.prefix + key] = msec_time() + int(ttl * 1000.0)