palantir / palantir/conjure-python

Union types break service serialization

Open
#323 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
27
Forks
19
Avg merge
12h 22m
Merged PRs (30d)
15

Description

What happened?

When we upgraded our conjure-python dependency we ran into runtime pyspark serialization issues. We previously could serialize a service object but post-conjure-python upgrade this same service was no longer serializable.

We suspect https://github.com/palantir/conjure-python/pull/320 or https://github.com/palantir/conjure-python/pull/221 broke serde behavior for us.

The pyspark error was:

py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.runJob.
: org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 1.0 failed 1 times, most recent failure: Lost task 0.0 in stage 1.0 (TID 1, localhost, executor driver): org.apache.spark.api.python.PythonException: Traceback (most recent call last):
  File "/opt/palantir/services/.4229/var/tmp/asset-install/85af169544daf00da129a002813aba21/spark/python/lib/pyspark.zip/pyspark/worker.py", line 413, in main
    func, profiler, deserializer, serializer = read_command(pickleSer, infile)
  File "/opt/palantir/services/.4229/var/tmp/asset-install/85af169544daf00da129a002813aba21/spark/python/lib/pyspark.zip/pyspark/worker.py", line 68, in read_command
    command = serializer._read_with_length(file)
  File "/opt/palantir/services/.4229/var/tmp/asset-install/85af169544daf00da129a002813aba21/spark/python/lib/pyspark.zip/pyspark/serializers.py", line 173, in _read_with_length
    return self.loads(obj)
  File "/opt/palantir/services/.4229/var/tmp/asset-install/85af169544daf00da129a002813aba21/spark/python/lib/pyspark.zip/pyspark/serializers.py", line 697, in loads
    return pickle.loads(obj, encoding=encoding)
AttributeError: type object 'AlertFailureResponse' has no attribute '_service_exception'

This was thrown when passing our service through a map function. This occurred even with zero data passed along. It was only the service code that previously worked.

Other conjure definitions:


      AlertResponse:
        union:
          failureResponse: AlertFailureResponse
          successResponse: AlertSuccessResponse

      AlertFailureResponse:
        fields:
          serviceException: ServiceException
      AlertSuccessResponse:
        fields:
          uuid: uuid

Our __conjure_generator_version__ is 3.12.1.

We mitigated the issue by building our Conjure service in a mapPartitions function which is likely a better practice anyway.

What did you want to happen?

We are not entirely sure on why these new type definitions are not serializable. I believe the fields are renamed in a way that pyspark's serialization cannot find but that is conjecture at this point.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the failure when the generated service is passed to a PySpark map function with zero data, then compare the union definitions and the changes in conjure-python PRs 320 and 221. Done means the generated AlertFailureResponse and AlertSuccessResponse types, including ServiceException, can be serialized in this scenario without the _service_exception error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.