[SPARK-55337][SS] Fix MemoryStream backward compatibility#54108
[SPARK-55337][SS] Fix MemoryStream backward compatibility#54108cloud-fan wants to merge 4 commits intoapache:masterfrom
Conversation
JIRA Issue Information=== Bug SPARK-55337 === This comment was automatically generated by GitHub Actions |
9d29544 to
6074dff
Compare
|
|
||
| // Deprecated: Used when an implicit SQLContext is in scope | ||
| @deprecated("Use MemoryStream.apply with an implicit SparkSession instead of SQLContext", "4.1.0") | ||
| def apply[A: Encoder]()(implicit sqlContext: SQLContext): MemoryStream[A] = |
There was a problem hiding this comment.
This is the problem. This is not backward compatible, as the previous API is def apply[A: Encoder](implicit sqlContext: SQLContext): MemoryStream[A] (no parentheses).
There is no way to keep both implicits. So the proposal here is to only keep implicit SQLContext, and require to pass SparkSession implicitly.
5825d62 to
14f1f0f
Compare
There was a problem hiding this comment.
@cloud-fan , we cannot create a follow-up for the released JIRA issue because your PR has a different fix version, 4.1.2 (or 4.2.0), instead of 4.1.0. Please create a new JIRA ID.
### What changes were proposed in this pull request? This is a followup to apache#52402 that addresses backward compatibility concerns: 1. Keep the original `implicit SQLContext` factory methods for full backward compatibility 2. Add new overloads with explicit `SparkSession` parameter for new code 3. Fix `TestGraphRegistrationContext` to provide implicit `spark` and `sqlContext` to avoid name shadowing issues in nested classes 4. Remove redundant `implicit val sparkSession` declarations from pipeline tests that are no longer needed with the fix ### Why are the changes needed? PR apache#52402 changed the MemoryStream API to use `implicit SparkSession` which broke backward compatibility for code that only has `implicit SQLContext` available. This followup ensures: - Old code continues to work without modification - New code can use SparkSession with explicit parameters - Internal implementation uses SparkSession (modernization from apache#52402) ### Does this PR introduce _any_ user-facing change? No. This maintains full backward compatibility while adding new API options. ### How was this patch tested? Existing tests pass. The API changes are additive. ### Was this patch authored or co-authored using generative AI tooling? Yes Co-authored-by: Cursor <cursoragent@cursor.com>
14f1f0f to
823133a
Compare
|
Thank you for getting a new JIRA ID. |
Remove the `apply[A: Encoder](numPartitions: Int, sparkSession: SparkSession)` factory method that creates a semantic trap - it can accidentally match calls like `MemoryStream[T](0, spark)` interpreting the first argument as `numPartitions` instead of `id`, causing zero partitions to be created and no data to flow. Users who need both `numPartitions` and explicit `SparkSession` can use the case class constructor directly: `new MemoryStream[A](id, sparkSession, Some(numPartitions))`. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
+1 (one minor comment which I think it's easily addressable) but probably good to make clear about below...
Do we know about the impact of this change? It seems to be complicated to think through the impact of this change (and a prior change, since it was turned out to be not backward compatible).
| * Creates a MemoryStream with explicit encoder and SparkSession. | ||
| * Usage: `MemoryStream(Encoders.scalaInt, spark)` | ||
| */ | ||
| def apply[A](encoder: Encoder[A], sparkSession: SparkSession): MemoryStream[A] = |
There was a problem hiding this comment.
I roughly remember the intention was to discourage the usage of SQLContext - if that's the case, we probably want to have the way to pass numPartitions parameter.
That said, looks like this method (explicit encoder instance) is newly added. Is there any usage of this? We don't seem to add the same in ContinuousMemoryStream and LowLatencyMemoryStream.
There was a problem hiding this comment.
It's used in quite some places like StreamingQueryManagerSuite
testQuietly("can start a streaming query with the same name in a different session") {
val session2 = spark.cloneSession()
val ds1 = MemoryStream(Encoders.INT, spark).toDS()
val ds2 = MemoryStream(Encoders.INT, session2).toDS()
There was a problem hiding this comment.
I've add a new overload to specific numPartitions with SparkSession.
| intsToDF(expected)(schema)) | ||
| } | ||
|
|
||
| test("LowPriorityMemoryStreamImplicits works with implicit sqlContext") { |
There was a problem hiding this comment.
lol we added tests in wrong place... the file seems to be for memory "sink", not memory "source".
It's internal API so this is not strictly a bug fix. It will break new Spark 4.1 app that start to use the new |
HeartSaVioR
left a comment
There was a problem hiding this comment.
+1 pending CI
It's unfortunate we broke the backward compatibility and fixing it would break it again, but I understand there is no better way. Thanks for fixing the nasty bug.
|
Shall we rerun the CI? It's good to try again before looking into CI failure and say it's not relevant to this change. |
What changes were proposed in this pull request?
This is a followup to #52402 that addresses backward compatibility concerns:
implicit SQLContextfactory methods for full backward compatibilitySparkSessionparameter for new codeTestGraphRegistrationContextto provide implicitsparkandsqlContextto avoid name shadowing issues in nested classesimplicit val sparkSessiondeclarations from pipeline tests that are no longer needed with the fixWhy are the changes needed?
PR #52402 changed the MemoryStream API to use
implicit SparkSessionwhich broke backward compatibility for code that only hasimplicit SQLContextavailable. This followup ensures:Does this PR introduce any user-facing change?
No. This maintains full backward compatibility while adding new API options.
How was this patch tested?
Existing tests pass. The API changes are additive.
Was this patch authored or co-authored using generative AI tooling?
Yes
Made with Cursor