Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(glue): support Ray jobs #23822

Merged
merged 7 commits into from
Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(glue): support Ray jobs: Add tests and update README
  • Loading branch information
moomindani committed Jan 25, 2023
commit 13983df012ba576e4a480f34514e89237f3ccda3
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-glue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ new glue.Job(stack, 'RayJob', {
executable: glue.JobExecutable.pythonRay({
glueVersion: glue.GlueVersion.V4_0,
pythonVersion: glue.PythonVersion.THREE_NINE,
script,
script: glue.Code.fromAsset(path.join(__dirname, 'job-script/hello_world.py')),
}),
workerType: glue.WorkerType.Z_2X,
workerCount: 2,
Expand Down
10 changes: 9 additions & 1 deletion packages/@aws-cdk/aws-glue/lib/job-executable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,18 @@ export class JobExecutable {
if (config.language !== JobLanguage.PYTHON) {
throw new Error('Python shell requires the language to be set to Python');
}
if ([GlueVersion.V0_9, GlueVersion.V2_0, GlueVersion.V3_0, GlueVersion.V4_0].includes(config.glueVersion)) {
if ([GlueVersion.V0_9, GlueVersion.V3_0, GlueVersion.V4_0].includes(config.glueVersion)) {
throw new Error(`Specified GlueVersion ${config.glueVersion.name} does not support Python Shell`);
}
}
if (JobType.RAY === config.type) {
if (config.language !== JobLanguage.PYTHON) {
throw new Error('Ray requires the language to be set to Python');
}
if ([GlueVersion.V0_9, GlueVersion.V1_0, GlueVersion.V2_0, GlueVersion.V3_0].includes(config.glueVersion)) {
throw new Error(`Specified GlueVersion ${config.glueVersion.name} does not support Ray`);
}
}
if (config.extraJarsFirst && [GlueVersion.V0_9, GlueVersion.V1_0].includes(config.glueVersion)) {
throw new Error(`Specified GlueVersion ${config.glueVersion.name} does not support extraJarsFirst`);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-glue/lib/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@ export class Job extends JobBase {
private setupSparkUI(executable: JobExecutableConfig, role: iam.IRole, props: SparkUIProps) {
if (JobType.PYTHON_SHELL === executable.type) {
throw new Error('Spark UI is not available for JobType.PYTHON_SHELL jobs');
} else if (JobType.RAY === executable.type) {
throw new Error('Spark UI is not available for JobType.RAY jobs');
}

const bucket = props.bucket ?? new s3.Bucket(this, 'SparkUIBucket');
Expand Down
25 changes: 23 additions & 2 deletions packages/@aws-cdk/aws-glue/test/job-executable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ describe('JobType', () => {

test('.PYTHON_SHELL should set the name correctly', () => expect(glue.JobType.PYTHON_SHELL.name).toEqual('pythonshell'));

test('.RAY should set the name correctly', () => expect(glue.JobType.RAY.name).toEqual('glueray'));

test('of(customName) should set the name correctly', () => expect(glue.JobType.of('CustomName').name).toEqual('CustomName'));
});

Expand Down Expand Up @@ -65,6 +67,15 @@ describe('JobExecutable', () => {
})).toThrow(/Python shell requires the language to be set to Python/);
});

test('with JobType.RAY and a language other than JobLanguage.PYTHON should throw', () => {
expect(() => glue.JobExecutable.of({
glueVersion: glue.GlueVersion.V4_0,
type: glue.JobType.RAY,
language: glue.JobLanguage.SCALA,
script,
})).toThrow(/Ray requires the language to be set to Python/);
});

test('with a non JobLanguage.PYTHON and extraPythonFiles set should throw', () => {
expect(() => glue.JobExecutable.of({
glueVersion: glue.GlueVersion.V3_0,
Expand All @@ -76,7 +87,7 @@ describe('JobExecutable', () => {
})).toThrow(/extraPythonFiles is not supported for languages other than JobLanguage.PYTHON/);
});

[glue.GlueVersion.V0_9, glue.GlueVersion.V2_0, glue.GlueVersion.V3_0, glue.GlueVersion.V4_0].forEach((glueVersion) => {
[glue.GlueVersion.V0_9, glue.GlueVersion.V3_0, glue.GlueVersion.V4_0].forEach((glueVersion) => {
test(`with JobType.PYTHON_SHELL and GlueVersion ${glueVersion} should throw`, () => {
expect(() => glue.JobExecutable.of({
type: glue.JobType.PYTHON_SHELL,
Expand Down Expand Up @@ -113,7 +124,7 @@ describe('JobExecutable', () => {
});
});

test('with PythonVersion set to PythonVersion.THREE_NINE and JobType not pythonshell should throw', () => {
test('with PythonVersion set to PythonVersion.THREE_NINE and JobType etl should throw', () => {
expect(() => glue.JobExecutable.of({
type: glue.JobType.ETL,
language: glue.JobLanguage.PYTHON,
Expand All @@ -132,5 +143,15 @@ describe('JobExecutable', () => {
script,
})).toBeDefined();
});

test('with PythonVersion PythonVersion.THREE_NINE and JobType ray should succeed', () => {
expect(glue.JobExecutable.of({
type: glue.JobType.RAY,
glueVersion: glue.GlueVersion.V4_0,
language: glue.JobLanguage.PYTHON,
pythonVersion: glue.PythonVersion.THREE_NINE,
script,
})).toBeDefined();
});
});
});
31 changes: 31 additions & 0 deletions packages/@aws-cdk/aws-glue/test/job.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ describe('WorkerType', () => {

test('.G_2X should set the name correctly', () => expect(glue.WorkerType.G_2X.name).toEqual('G.2X'));

test('.G_025X should set the name correctly', () => expect(glue.WorkerType.G_025X.name).toEqual('G.025X'));

test('.Z_2X should set the name correctly', () => expect(glue.WorkerType.Z_2X.name).toEqual('Z.2X'));

test('of(customType) should set name correctly', () => expect(glue.WorkerType.of('CustomType').name).toEqual('CustomType'));
});

Expand Down Expand Up @@ -604,6 +608,33 @@ describe('Job', () => {
});
});

describe('ray job', () => {
test('with unsupported glue version should throw', () => {
expect(() => new glue.Job(stack, 'Job', {
executable: glue.JobExecutable.pythonRay({
glueVersion: glue.GlueVersion.V3_0,
pythonVersion: glue.PythonVersion.THREE_NINE,
script,
}),
workerType: glue.WorkerType.Z_2X,
workerCount: 2,
})).toThrow('Specified GlueVersion 3.0 does not support Ray');
});

test('with unsupported Spark UI prop should throw', () => {
expect(() => new glue.Job(stack, 'Job', {
executable: glue.JobExecutable.pythonRay({
glueVersion: glue.GlueVersion.V4_0,
pythonVersion: glue.PythonVersion.THREE_NINE,
script,
}),
workerType: glue.WorkerType.Z_2X,
workerCount: 2,
sparkUI: { enabled: true },
})).toThrow('Spark UI is not available for JobType.RAY');
});
});


test('etl job with all props should synthesize correctly', () => {
new glue.Job(stack, 'Job', {
Expand Down