mirror of
				https://github.com/balkian/bitter.git
				synced 2025-10-30 23:28:18 +00:00 
			
		
		
		
	Parallel processing and future
This commit is contained in:
		| @@ -3,5 +3,8 @@ Bitter module. A library and cli for Twitter using python-twitter. | |||||||
| http://github.com/balkian/bitter | http://github.com/balkian/bitter | ||||||
| """ | """ | ||||||
|  |  | ||||||
| __version__ = '0.4.1' | from future.standard_library import install_aliases | ||||||
|  | install_aliases() | ||||||
|  |  | ||||||
|  | __version__ = '0.5.0' | ||||||
| __all__ = ['cli', 'config', 'crawlers', 'models', 'utils' ] | __all__ = ['cli', 'config', 'crawlers', 'models', 'utils' ] | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ import sqlalchemy.types | |||||||
| import threading | import threading | ||||||
| import sqlite3 | import sqlite3 | ||||||
|  |  | ||||||
| from six.moves import map, filter, queue |  | ||||||
| from sqlalchemy import exists | from sqlalchemy import exists | ||||||
|  |  | ||||||
| from bitter import utils, models, crawlers | from bitter import utils, models, crawlers | ||||||
|   | |||||||
| @@ -6,9 +6,12 @@ import signal | |||||||
| import sys | import sys | ||||||
| import sqlalchemy | import sqlalchemy | ||||||
| import os | import os | ||||||
|  | import multiprocessing | ||||||
|  | from multiprocessing.pool import ThreadPool | ||||||
|  |  | ||||||
| from itertools import islice | from itertools import islice | ||||||
| from contextlib import contextmanager | from contextlib import contextmanager | ||||||
|  | from itertools import zip_longest | ||||||
|  |  | ||||||
| from twitter import TwitterHTTPError | from twitter import TwitterHTTPError | ||||||
|  |  | ||||||
| @@ -23,6 +26,16 @@ def signal_handler(signal, frame): | |||||||
|     logger.info('You pressed Ctrl+C!') |     logger.info('You pressed Ctrl+C!') | ||||||
|     sys.exit(0) |     sys.exit(0) | ||||||
|  |  | ||||||
|  | def chunk(iterable, n, fillvalue=None): | ||||||
|  |     args = [iter(iterable)] * n | ||||||
|  |     return zip_longest(*args, fillvalue=fillvalue) | ||||||
|  |  | ||||||
|  | def parallel(func, source, chunksize=0, numcpus=multiprocessing.cpu_count()): | ||||||
|  |     if chunksize: | ||||||
|  |         source = chunk(source, chunksize) | ||||||
|  |     p = ThreadPool(numcpus) | ||||||
|  |     for i in p.imap(func, source): | ||||||
|  |         yield i | ||||||
|  |  | ||||||
| def get_credentials_path(credfile=None): | def get_credentials_path(credfile=None): | ||||||
|     if not credfile: |     if not credfile: | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| sqlalchemy | sqlalchemy | ||||||
| twitter | twitter | ||||||
| click | click | ||||||
| six | future | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| from unittest import TestCase | from unittest import TestCase | ||||||
|  |  | ||||||
| import os | import os | ||||||
|  | import types | ||||||
|  |  | ||||||
| from bitter import utils | from bitter import utils | ||||||
| from bitter import config as c | from bitter import config as c | ||||||
| @@ -46,5 +47,15 @@ class TestUtils(TestCase): | |||||||
|         print(utils.get_credentials()) |         print(utils.get_credentials()) | ||||||
|         assert not utils.get_credentials(user="test") |         assert not utils.get_credentials(user="test") | ||||||
|  |  | ||||||
|          |     def test_parallel(self): | ||||||
|  |         import time | ||||||
|  |         def echo(i): | ||||||
|  |             time.sleep(2) | ||||||
|  |             return i | ||||||
|  |         tic = time.time() | ||||||
|  |         resp = utils.parallel(echo, [1,2,3]) | ||||||
|  |         assert isinstance(resp, types.GeneratorType) | ||||||
|  |         assert list(resp) == [1,2,3] | ||||||
|  |         toc = time.time() | ||||||
|  |         assert (tic-toc) < 6000 | ||||||
|          |          | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user