def close(self):
        """
        Close all PrefetchIterators in this pipeline

        PrefetchIterators have internal resources that need to be properly managed by calling close() manually.
        Failure to do so can lead to dangling processes and threads, or the PrefetchIterator hanging on finalization.
        Note that it is not correct to rely on the garbage collector to destroy PrefetchIterators
        as CPython does not assure that the finalizer (__del__) of a PrefetchIterator will be called.

        This function, which is implemented for every CheckpointableIterator, recursively traverses all preceeding
        iterators and closes all PrefetchIterators in the pipeline.
        For pipelines that do not contain PrefetchIterators this function has no effect.
        """
        if not self._is_closed:
            self._is_closed = True
            self._shutdown()
        self._source_iterator.close()

        Close all PrefetchIterators in this pipeline

        PrefetchIterators have internal resources that need to be properly managed by calling close() manually.
        Failure to do so can lead to dangling processes and threads, or the PrefetchIterator hanging on finalization.
        Note that it is not correct to rely on the garbage collector to destroy PrefetchIterators
        as CPython does not assure that the finalizer (__del__) of a PrefetchIterator will be called.

        This function, which is implemented for every CheckpointableIterator, recursively traverses all preceeding
        iterators and closes all PrefetchIterators in the pipeline.
        For pipelines that do not contain PrefetchIterators this function has no effect.
        
kosmos-2/infinibatch/infinibatch/iterators.py