class_docstr: Abstract parent class
class_docstr_tok: ["Abstract","parent","class"]
docstr: This method is invoked by the ActiveMemoryManager every few seconds, or
  whenever the user invokes ``client.amm.run_once``.
  
  It is an iterator that must emit
  :class:`~distributed.active_memory_manager.Suggestion` objects:
  
  - ``Suggestion("replicate", <TaskState>)``
  - ``Suggestion("replicate", <TaskState>, {subset of potential workers to replicate to})``
  - ``Suggeston("drop", <TaskState>)``
  - ``Suggestion("drop", <TaskState>, {subset of potential workers to drop from})``
  
  Each element yielded indicates the desire to create or destroy a single replica
  of a key. If a subset of workers is not provided, it defaults to all workers on
  the cluster. Either the ActiveMemoryManager or the Worker may later decide to
  disregard the request, e.g. because it would delete the last copy of a key or
  because the key is currently needed on that worker.
  
  You may optionally retrieve which worker it was decided the key will be
  replicated to or dropped from, as follows:
  
  .. code-block:: python
  
     choice = (yield Suggestion("replicate", ts))
  
  ``choice`` is either a WorkerState or None; the latter is returned if the
  ActiveMemoryManager chose to disregard the request.
  
  The current pending (accepted) suggestions can be inspected on
  ``self.manager.pending``; this includes the suggestions previously yielded by
  this same method.
  
  The current memory usage on each worker, *downstream of all pending
  suggestions*, can be inspected on ``self.manager.workers_memory``.
docstr_tok: ["This","method","is","invoked","by","the","ActiveMemoryManager","every","few","seconds",",","or","whenever","the","user","invokes","``","client.amm.run_once","``",".","It","is","an","iterator","that","must","emit",":","class",":","`","~distributed.active_memory_manager.Suggestion","`","objects",":","-","``","Suggestion","(","``","replicate","''",",","<","TaskState",">",")","``","-","``","Suggestion","(","``","replicate","''",",","<","TaskState",">",",","{","subset","of","potential","workers","to","replicate","to","}",")","``","-","``","Suggeston","(","``","drop","''",",","<","TaskState",">",")","``","-","``","Suggestion","(","``","drop","''",",","<","TaskState",">",",","{","subset","of","potential","workers","to","drop","from","}",")","``","Each","element","yielded","indicates","the","desire","to","create","or","destroy","a","single","replica","of","a","key",".","If","a","subset","of","workers","is","not","provided",",","it","defaults","to","all","workers","on","the","cluster",".","Either","the","ActiveMemoryManager","or","the","Worker","may","later","decide","to","disregard","the","request",",","e.g",".","because","it","would","delete","the","last","copy","of","a","key","or","because","the","key","is","currently","needed","on","that","worker",".","You","may","optionally","retrieve","which","worker","it","was","decided","the","key","will","be","replicated","to","or","dropped","from",",","as","follows",":","..","code-block",":",":","python","choice","=","(","yield","Suggestion","(","``","replicate","''",",","ts",")",")","``","choice","``","is","either","a","WorkerState","or","None",";","the","latter","is","returned","if","the","ActiveMemoryManager","chose","to","disregard","the","request",".","The","current","pending","(","accepted",")","suggestions","can","be","inspected","on","``","self.manager.pending","``",";","this","includes","the","suggestions","previously","yielded","by","this","same","method",".","The","current","memory","usage","on","each","worker",",","*","downstream","of","all","pending","suggestions","*",",","can","be","inspected","on","``","self.manager.workers_memory","``","."]
code: def run(
      self,
  ) -> SuggestionGenerator:
      """This method is invoked by the ActiveMemoryManager every few seconds, or
      whenever the user invokes ``client.amm.run_once``.
  
      It is an iterator that must emit
      :class:`~distributed.active_memory_manager.Suggestion` objects:
  
      - ``Suggestion("replicate", <TaskState>)``
      - ``Suggestion("replicate", <TaskState>, {subset of potential workers to replicate to})``
      - ``Suggeston("drop", <TaskState>)``
      - ``Suggestion("drop", <TaskState>, {subset of potential workers to drop from})``
  
      Each element yielded indicates the desire to create or destroy a single replica
      of a key. If a subset of workers is not provided, it defaults to all workers on
      the cluster. Either the ActiveMemoryManager or the Worker may later decide to
      disregard the request, e.g. because it would delete the last copy of a key or
      because the key is currently needed on that worker.
  
      You may optionally retrieve which worker it was decided the key will be
      replicated to or dropped from, as follows:
  
      .. code-block:: python
  
         choice = (yield Suggestion("replicate", ts))
  
      ``choice`` is either a WorkerState or None; the latter is returned if the
      ActiveMemoryManager chose to disregard the request.
  
      The current pending (accepted) suggestions can be inspected on
      ``self.manager.pending``; this includes the suggestions previously yielded by
      this same method.
  
      The current memory usage on each worker, *downstream of all pending
      suggestions*, can be inspected on ``self.manager.workers_memory``.
      """
  
imports: from __future__ import annotations
  import abc
  import logging
  from collections import defaultdict
  from collections.abc import Generator
  from typing import TYPE_CHECKING, Any, Literal, NamedTuple, Union
  import dask
  from dask.typing import Key
  from dask.utils import parse_timedelta
  from distributed import client
  from distributed import scheduler
  from distributed.compatibility import PeriodicCallback
  from distributed.core import Status
  from distributed.metrics import time
  from distributed.utils import import_term, log_errors
label_desc: Use image node_id 2 for calling the ActiveMemoryManagerPolicy obj's underlying member method code with example usage: obj.run() without return types