blob: 9afbf2a93e7fa45220ebd0c960d5d15f487e888a [file]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
Streaming query management.
This module re-exports the PyO3-implemented streaming query classes that provide
the client-side API for managing and inspecting streaming queries, and extends them
with Python-side listener bus implementation.
"""
import json
import warnings
from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Union
from threading import Thread, Lock
from pyspark import cloudpickle
from pyspark.sql.streaming.listener import (
StreamingQueryListener,
QueryStartedEvent,
QueryProgressEvent,
QueryIdleEvent,
QueryTerminatedEvent,
)
from pyspark._pyspark import (
StreamingQuery as _StreamingQuery,
StreamingQueryManager as _StreamingQueryManager,
StreamingQueryStatus as _StreamingQueryStatus,
StreamingQueryException as _StreamingQueryException,
)
if TYPE_CHECKING:
from pyspark.sql.session import SparkSession
# StreamingQueryEventType values (spark.connect.StreamingQueryEventType); the Rust
# listener stream yields these as the event_type int alongside each event's JSON.
_QUERY_PROGRESS_EVENT = 1
_QUERY_TERMINATED_EVENT = 2
_QUERY_IDLE_EVENT = 3
# Re-export the core classes from the Rust extension
StreamingQuery = _StreamingQuery
StreamingQueryStatus = _StreamingQueryStatus
StreamingQueryException = _StreamingQueryException
def _dispatch_listener_event(listener, event_type, event_json):
"""Deserialize a listener event and invoke the matching callback on ``listener``.
Called from the native (Rust) listener bus for each event. Mirrors the reference
``StreamingQueryListenerBus`` dispatch: build the typed event and route it to
onQueryProgress / onQueryIdle / onQueryTerminated. Callback exceptions are surfaced
as warnings so one listener cannot break the dispatch thread.
"""
try:
j = json.loads(event_json)
if event_type == _QUERY_PROGRESS_EVENT:
listener.onQueryProgress(QueryProgressEvent.fromJson(j))
elif event_type == _QUERY_IDLE_EVENT:
listener.onQueryIdle(QueryIdleEvent.fromJson(j))
elif event_type == _QUERY_TERMINATED_EVENT:
listener.onQueryTerminated(QueryTerminatedEvent.fromJson(j))
except Exception as e: # noqa: BLE001
warnings.warn(f"Listener callback raised exception: {e}")
# ``spark.streams`` returns the native (Rust) StreamingQueryManager, which owns the
# client-side listener bus: addListener / removeListener / close are implemented in the
# Rust core (so Rust clients get the listener feature too). Re-export it as the public
# class.
StreamingQueryManager = _StreamingQueryManager
__all__ = [
"StreamingQuery",
"StreamingQueryManager",
"StreamingQueryStatus",
"StreamingQueryException",
]