docstr: When the client attempts to add or remove a subscription callback,
  validate and perform the requested operation.
  
  Args:
      msg (dict): the message from the client
      table_or_view {Table|View} : the instance that the subscription
          will be called on.
      post_callback (callable): a method that notifies the client with
          new data.
      client_id (str) : a unique str id that identifies the
          `PerspectiveSession` object that is passing the message.
docstr_tok: ["When","the","client","attempts","to","add","or","remove","a","subscription","callback",",","validate","and","perform","the","requested","operation",".","Args",":","msg","(","dict",")",":","the","message","from","the","client","table_or_view","{","Table|View","}",":","the","instance","that","the","subscription","will","be","called","on",".","post_callback","(","callable",")",":","a","method","that","notifies","the","client","with","new","data",".","client_id","(","str",")",":","a","unique","str","id","that","identifies","the","`","PerspectiveSession","`","object","that","is","passing","the","message","."]
code: def _process_subscribe(
      self, msg, table_or_view, post_callback, client_id
  ):
      """When the client attempts to add or remove a subscription callback,
      validate and perform the requested operation.
  
      Args:
          msg (dict): the message from the client
          table_or_view {Table|View} : the instance that the subscription
              will be called on.
          post_callback (callable): a method that notifies the client with
              new data.
          client_id (str) : a unique str id that identifies the
              `PerspectiveSession` object that is passing the message.
      """
      try:
          callback = None
          callback_id = msg.get("callback_id", None)
          method = msg.get("method", None)
          args = msg.get("args", [])
          if method and method[:2] == "on":
              # wrap the callback
              callback = partial(
                  self.callback, msg=msg, post_callback=post_callback
              )
              if callback_id:
                  self._callback_cache.add_callback(
                      {
                          "client_id": client_id,
                          "callback_id": callback_id,
                          "callback": callback,
                          "name": msg.get("name", None),
                      }
                  )
          elif callback_id is not None:
              # pop the callback from the cache of the manager, and
              # remove each of them from the underlying table or view
              popped_callbacks = self._callback_cache.pop_callbacks(
                  client_id, callback_id
              )
  
              for callback in popped_callbacks:
                  getattr(table_or_view, method)(callback["callback"])
          if callback is not None:
              # call the underlying method on the Table or View, and apply
              # the dictionary of kwargs that is passed through.
              if method == "on_update":
                  # If there are no arguments, make sure we call `on_update`
                  # with mode set to "none".
                  mode = {"mode": "none"}
                  if len(args) > 0:
                      mode = args[0]
                  getattr(table_or_view, method)(callback, **mode)
              else:
                  getattr(table_or_view, method)(callback)
          else:
              logging.info(
                  "callback not found for remote call {}".format(msg)
              )
      except Exception as error:
          error_string = str(error)
          message = self._make_error_message(msg["id"], error_string)
          logging.error(
              "[PerspectiveManager._process_subscribe] %s", error_string
          )
          post_callback(self._message_to_json(msg["id"], message))
  
imports: import datetime
  import json
  import logging
  from collections import deque
  from functools import partial
  from ..core.exception import PerspectiveError
  from ..table import PerspectiveCppError, Table
  from ..table._callback_cache import _PerspectiveCallBackCache
  from ..table._date_validator import _PerspectiveDateValidator
label_desc: Use image node_id 6 for calling the _PerspectiveManagerInternal obj's underlying member method code with example usage: obj._process_subscribe(msg, table_or_view, post_callback, client_id) without return types