Skip to main content

Simple package to enhance Python's concurrent.futures for memory efficiency

Project description

future-map

future-map is a Python library to use together with the official concurrent.futures module.

Why future-map?

Because it's difficult to deal with an infinite or huge input with concurrent.future.ThreadPoolExecutor and concurrent.future.ProcessPoolExecutor. See the following example.

from concurrent.futures import ThreadPoolExecutor

def make_input(length):
    return range(length)

def make_infinite_input():
    count = 0
    while True:
        yield count
        count += 1

def process(value):
    return value * 2

if __name__ == '__main__':
    with ThreadPoolExecutor(max_workers=3) as executor:
        # Works well
        for value in executor.map(process, make_input(10)):
            print('Doubled value:', value)

        # This freezes the process and memory usage keeps growing
        for value in executor.map(process, make_infinite_input()):
            print('Doubled value:', value)

Installation

Use the package manager pip to install future-map.

$ pip install future-map

Usage

This library provides FutureMap. See the following example.

from future_map import FutureMap
from concurrent.futures import ThreadPoolExecutor

def make_infinite_input():
    count = 0
    while True:
        yield count
        count += 1

def process(value):
    return value * 2

if __name__ == '__main__':
    with ThreadPoolExecutor(max_workers=3) as executor:
        fm = FutureMap(
            lambda value: executor.submit(process, value),
            make_infinite_input(), buffersize=5
        )
        for value in fm:
            print('Doubled value:', value)

For more complicated use case:

import time
from concurrent.futures import ThreadPoolExecutor

from future_map import FutureMap

class APIClient:
    def __init__(self, max_connections):
        self.__max_connections = max_connections
        self.__executor = None

    def __enter__(self):
        self.__executor = ThreadPoolExecutor(max_workers=self.__max_connections)
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.__executor.shutdown()
        self.__executor = None

    def call(self, url):
        time.sleep(1)
        return "Response from {}".format(url)

    def call_async(self, url):
        if self.__executor is None:
            raise Exception("call_async needs to be called in the runtime context with this APIClient")
        return self.__executor.submit(self.call, url)


def make_urls():
    for i in range(100):
        yield "https://example.com/api/resources/{}".format(i)

if __name__ == '__main__':
    with APIClient(max_connections=3) as api_client:
        for response in FutureMap(api_client.call_async, make_urls(), buffersize=5):
            print(response)

API

FutureMap(fn, iterable, buffersize)

Constructor of FutureMap.

FutureMap is an iterable object that maps an iterable object (iterable argument) to a function (fn argument), waits until each future object is done, and yields each result.

Please note that this object will yield unordered results.

  • Arguments
    • fn: Callable object that takes an argument from iterable, and return a concurrent.futures.Future.
    • iterable: Iterable object.
    • buffersize: Maximum size of internal buffer. Each concurrent.futures.Future object is stored in the buffer until it's done. If the buffer is fulfilled, FutureMap stops reading values from iterable.
  • Return
    • FutureMap instance

future_map(fn, iterable, buffersize)

Alias of FutureMap. You can use this function if you prefer a similar syntax with the map function.

For more details, please refer to FutureMap(fn, iterable, buffersize).

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

future-map-0.1.2.tar.gz (4.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

future_map-0.1.2-py3-none-any.whl (4.0 kB view details)

Uploaded Python 3

File details

Details for the file future-map-0.1.2.tar.gz.

File metadata

  • Download URL: future-map-0.1.2.tar.gz
  • Upload date:
  • Size: 4.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.8 CPython/3.8.5 Darwin/20.2.0

File hashes

Hashes for future-map-0.1.2.tar.gz
Algorithm Hash digest
SHA256 1c178b1028c4c62fd97854f3153e20246087f3b6a2b6502155ca641a8d213f2c
MD5 b03291c1788e298bb189d7c607c9bee0
BLAKE2b-256 499638b0510eca259b0197d81c9b9e92a4fe307f1199fba4b82745d1f33f85d7

See more details on using hashes here.

File details

Details for the file future_map-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: future_map-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 4.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.8 CPython/3.8.5 Darwin/20.2.0

File hashes

Hashes for future_map-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 56f824f994d729502326670b1ba209ba700b1f6d5ae2aa2220496fbba7a3d67a
MD5 a47a6e29482d980df02d779db12d0e30
BLAKE2b-256 be5a3dbac96920e3910c0a9e26950a99236e3d89e2e06010ff0b0853eac0fba1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page