[MediaWiki-commits] [Gerrit] Add a monotonic clock implementation - change (mediawiki...EventLogging)

2014-11-29 Thread jenkins-bot (Code Review)
jenkins-bot has submitted this change and it was merged.

Change subject: Add a monotonic clock implementation
..


Add a monotonic clock implementation

I needed a monotonic clock for a change I wanted to make to PeriodicThread.
Python 3.3 introduced `time.monotonic`, but there's nothing equivalent for
earlier versions of Python. So I set out to write a fallback implementation.
One thing led to another, and I ended up with a small, self-standing library,
which I published to GitHub and PyPI:

- https://github.com/atdt/monotonic
- https://pypi.python.org/pypi/monotonic

So now there's the question of how to integrate it with EventLogging. We could
treat it like a normal external dependency, but that's a lot of inconvenience
for a library that fits in a single file and of which I am the primary author.
So I decided to just bundle it here instead.

Change-Id: If6166d2353f51d30a447b0a6405dbe8871431502
---
M server/eventlogging/compat.py
A server/eventlogging/lib/__init__.py
A server/eventlogging/lib/monotonic.py
M server/tests/test_compat.py
4 files changed, 147 insertions(+), 2 deletions(-)

Approvals:
  Ori.livneh: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/server/eventlogging/compat.py b/server/eventlogging/compat.py
index e85da14..608bc42 100644
--- a/server/eventlogging/compat.py
+++ b/server/eventlogging/compat.py
@@ -14,12 +14,22 @@
 # pylint: disable=E0611, F0401, E1101
 from __future__ import unicode_literals
 
+import ctypes
+import ctypes.util
 import functools
 import hashlib
 import operator
 import sys
+import time
 import uuid
+import warnings
 
+try:
+from .lib.monotonic import monotonic as monotonic_clock
+except ImportError:
+warnings.warn('Using non-monotonic time.time() as last-resort fallback '
+  'for eventlogging.monotonic_clock()', RuntimeWarning)
+monotonic_clock = time.time
 
 try:
 import simplejson as json
@@ -27,9 +37,11 @@
 import json
 
 
-__all__ = ('http_get', 'items', 'json', 'unquote_plus', 'urisplit',
-   'urlopen', 'uuid5')
+__all__ = ('http_get', 'items', 'json', 'monotonic_clock', 'unquote_plus',
+   'urisplit', 'urlopen', 'uuid5')
 
+LIBC = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
+CLOCK_MONOTONIC_RAW = 4
 PY3 = sys.version_info[0] == 3
 
 if PY3:
diff --git a/server/eventlogging/lib/__init__.py 
b/server/eventlogging/lib/__init__.py
new file mode 100644
index 000..e69de29
--- /dev/null
+++ b/server/eventlogging/lib/__init__.py
diff --git a/server/eventlogging/lib/monotonic.py 
b/server/eventlogging/lib/monotonic.py
new file mode 100644
index 000..d6dff9f
--- /dev/null
+++ b/server/eventlogging/lib/monotonic.py
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+"""
+  monotonic
+  ~
+
+  This module provides a ``monotonic()`` function which returns the
+  value (in fractional seconds) of a clock which never goes backwards.
+
+  On Python 3.3 or newer, ``monotonic`` will be an alias of
+  ``time.monotonic`` from the standard library. On older versions,
+  it will fall back to an equivalent implementation:
+
+  +-++
+  | Linux, BSD  | clock_gettime(3)   |
+  +-++
+  | Windows | GetTickCount64 |
+  +-++
+  | OS X| mach_absolute_time |
+  +-++
+
+  If no suitable implementation exists for the current platform,
+  attempting to import this module (or to import from it) will
+  cause a RuntimeError exception to be raised.
+
+
+  Copyright 2014 Ori Livneh 
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+"""
+from __future__ import absolute_import, division
+
+import ctypes
+import ctypes.util
+import os
+import sys
+import time
+
+
+__all__ = ('monotonic',)
+
+try:
+monotonic = time.monotonic
+except AttributeError:
+try:
+if sys.platform == 'darwin':  # OS X, iOS
+# See Technical Q&A QA1398 of the Mac Developer Library:
+#  
+libc = ctypes.CDLL('libc.dylib', use_errno=True)
+
+class mach_timebase_info_data_t(ctypes.Structure):
+"""System timebase info. Defined in ."""
+_fields_ = (('numer', ctypes.c_uint32),
+('denom', ctypes.c_uint32))
+
+mach_absolute_time = libc.mach_absolute_time

[MediaWiki-commits] [Gerrit] Add a monotonic clock implementation - change (mediawiki...EventLogging)

2014-11-22 Thread Ori.livneh (Code Review)
Ori.livneh has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/175320

Change subject: Add a monotonic clock implementation
..

Add a monotonic clock implementation

Uses time.monotonic() if available (Python 3.3+), otherwise calls
clock_gettime(CLOCK_MONOTONIC_RAW) via ctypes.

Change-Id: If6166d2353f51d30a447b0a6405dbe8871431502
---
M server/eventlogging/compat.py
1 file changed, 30 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/EventLogging 
refs/changes/20/175320/1

diff --git a/server/eventlogging/compat.py b/server/eventlogging/compat.py
index e85da14..c522291 100644
--- a/server/eventlogging/compat.py
+++ b/server/eventlogging/compat.py
@@ -14,11 +14,15 @@
 # pylint: disable=E0611, F0401, E1101
 from __future__ import unicode_literals
 
+import ctypes
+import ctypes.util
 import functools
 import hashlib
 import operator
 import sys
+import time
 import uuid
+import warnings
 
 
 try:
@@ -30,6 +34,8 @@
 __all__ = ('http_get', 'items', 'json', 'unquote_plus', 'urisplit',
'urlopen', 'uuid5')
 
+LIBC = ctypes.CDLL(ctypes.util.find_library('c'))
+CLOCK_MONOTONIC_RAW = 4
 PY3 = sys.version_info[0] == 3
 
 if PY3:
@@ -84,3 +90,27 @@
 # variant expects unicode strings in both Python 2 and Python 3.
 hash = hashlib.sha1(namespace.bytes + name.encode('utf-8')).digest()
 return uuid.UUID(bytes=hash[:16], version=5)
+
+
+class timespec(ctypes.Structure):
+"""The timespec struct, as specified in  on POSIX systems."""
+_fields_ = [('tv_sec', ctypes.c_long), ('tv_nsec', ctypes.c_long)]
+
+
+def _monotonic_time():
+"""Monotonic clock, cannot go backward."""
+ts = timespec()
+LIBC.clock_gettime(CLOCK_MONOTONIC_RAW, ctypes.byref(ts))
+return ts.tv_sec + (ts.tv_nsec * 1e-9)
+
+
+try:
+monotonic_time = time.monotonic  # Python 3.3+
+except AttributeError:
+try:
+_monotonic_time()
+else:
+monotonic_time = _monotonic_time
+except (AttributeError, OSError):
+warnings.warn('Using non-monotonic `time.time`.', RuntimeWarning)
+monotonic_time = time.time()

-- 
To view, visit https://gerrit.wikimedia.org/r/175320
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If6166d2353f51d30a447b0a6405dbe8871431502
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/EventLogging
Gerrit-Branch: master
Gerrit-Owner: Ori.livneh 

___
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits