Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg)](https://github.com/procrastinate-org/procrastinate/blob/main/CODE_OF_CONDUCT.md)
[![Discord](https://img.shields.io/discord/1197292025725329549?logo=discord&logoColor=white&label=Discord&color=%237289da)](https://discord.gg/JWZeNq6P6Z)

**Procrastinate is looking for** [additional maintainers!](https://github.com/procrastinate-org/procrastinate/discussions/748)
### Fork changes

1. Added `result` column to `jobs` table so failed job can store it's failure reason

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor grammatical issue: "it's" should be "its".

"it's" is a contraction of "it is", while "its" is the possessive form needed here.

📝 Suggested fix
-1. Added `result` column to `jobs` table so failed job can store it's failure reason
+1. Added `result` column to `jobs` table so a failed job can store its failure reason
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1. Added `result` column to `jobs` table so failed job can store it's failure reason
1. Added `result` column to `jobs` table so a failed job can store its failure reason
🤖 Prompt for AI Agents
In `@README.md` at line 15, Fix the grammatical typo in the README line
referencing the `result` column on the `jobs` table: change "it's" to the
possessive "its" so the sentence reads that a failed job can store its failure
reason; update the string where the text mentions `result` and `jobs` to correct
the possessive form.


**Procrastinate is looking for
** [additional maintainers!](https://github.com/procrastinate-org/procrastinate/discussions/748)
Comment on lines +13 to +18

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix heading level and malformed bold markdown.

Two issues:

  1. The heading should be ## (h2) instead of ### (h3) to follow proper heading hierarchy after h1.
  2. The bold markdown on line 17-18 is malformed - the ** markers are split across lines.
📝 Suggested fix
-### Fork changes
+## Fork changes

 1. Added `result` column to `jobs` table so failed job can store it's failure reason

-**Procrastinate is looking for
-** [additional maintainers!](https://github.com/procrastinate-org/procrastinate/discussions/748)
+**Procrastinate is looking for [additional maintainers!](https://github.com/procrastinate-org/procrastinate/discussions/748)**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Fork changes
1. Added `result` column to `jobs` table so failed job can store it's failure reason
**Procrastinate is looking for
** [additional maintainers!](https://github.com/procrastinate-org/procrastinate/discussions/748)
## Fork changes
1. Added `result` column to `jobs` table so failed job can store it's failure reason
**Procrastinate is looking for [additional maintainers!](https://github.com/procrastinate-org/procrastinate/discussions/748)**
🧰 Tools
🪛 LanguageTool

[style] ~18-~18: Using many exclamation marks might seem excessive (in this case: 8 exclamation marks for a text that’s 3189 characters long)
Context: ...s looking for ** [additional maintainers!](https://github.com/procrastinate-org/p...

(EN_EXCESSIVE_EXCLAMATION)

🪛 markdownlint-cli2 (0.20.0)

[warning] 13-13: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 Prompt for AI Agents
In `@README.md` around lines 13 - 18, Change the "Fork changes" heading from h3 to
h2 by replacing "### Fork changes" with "## Fork changes" and fix the malformed
bold markdown by combining the split "**Procrastinate is looking for" and
"additional maintainers!**" into a single bolded phrase such as "**Procrastinate
is looking for additional maintainers!**" so the bold markers are on the same
line around the full text.


Procrastinate is an open-source Python 3.10+ distributed task processing
library, leveraging PostgreSQL 13+ to store task definitions, manage locks and
Expand All @@ -31,12 +36,14 @@ import procrastinate
# Make an app in your code
app = procrastinate.App(connector=procrastinate.SyncPsycopgConnector())


# Then define tasks
@app.task(queue="sums")
def sum(a, b):
with open("myfile", "w") as f:
f.write(str(a + b))


with app.open():
# Launch a job
sum.defer(a=3, b=5)
Expand Down Expand Up @@ -72,11 +79,13 @@ import procrastinate
# Make an app in your code
app = procrastinate.App(connector=procrastinate.PsycopgConnector())


# Define tasks using coroutine functions
@app.task(queue="sums")
async def sum(a, b):
await asyncio.sleep(a + b)


async with app.open_async():
# Launch a job
await sum.defer_async(a=3, b=5)
Expand Down Expand Up @@ -106,7 +115,11 @@ If you encounter a bug, or want to get in touch, you're always welcome to open a
[ticket].

[docs]: https://procrastinate.readthedocs.io/

[procrastinate]: https://en.wikipedia.org/wiki/Procrastination

[django]: https://procrastinate.readthedocs.io/en/stable/howto/django/configuration.html

[quickstart]: https://procrastinate.readthedocs.io/en/stable/quickstart.html

[ticket]: https://github.com/procrastinate-org/procrastinate/issues/new
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from __future__ import annotations

from django.db import migrations

from .. import migrations_utils


class Migration(migrations.Migration):
operations = [
migrations_utils.RunProcrastinateSQL(
name="03.08.00_01_pre_result_to_job_procedure.sql"
),
]
name = "0042_pre_result_column"
dependencies = [
("procrastinate", "0041_post_retry_failed_job"),
]
5 changes: 4 additions & 1 deletion procrastinate/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ async def finish_job(
job: jobs_module.Job,
status: jobs_module.Status,
delete_job: bool,
exc_info: bool | BaseException = False,
) -> None:
"""
Set a job to its final state (``succeeded``, ``failed`` or ``aborted``).
Expand All @@ -303,20 +304,22 @@ async def finish_job(
"""
assert job.id # TODO remove this
await self.finish_job_by_id_async(
job_id=job.id, status=status, delete_job=delete_job
job_id=job.id, status=status, delete_job=delete_job, exc_info=exc_info
)

async def finish_job_by_id_async(
self,
job_id: int,
status: jobs_module.Status,
delete_job: bool,
exc_info: bool | BaseException = False,
) -> None:
await self.connector.execute_query_async(
query=sql.queries["finish_job"],
job_id=job_id,
status=status.value,
delete_job=delete_job,
exc_info=str(exc_info) if exc_info else None,
)

def cancel_job_by_id(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
ALTER TABLE procrastinate_jobs ADD COLUMN result TEXT;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

drop function if exists "public"."procrastinate_finish_job_v1"(job_id bigint, end_status procrastinate_job_status, delete_job boolean);


CREATE FUNCTION procrastinate_finish_job_v1(job_id bigint, end_status procrastinate_job_status, delete_job boolean, job_result text default null)
RETURNS void
LANGUAGE plpgsql
AS $$
DECLARE
_job_id bigint;
BEGIN
IF end_status NOT IN ('succeeded', 'failed', 'aborted') THEN
RAISE 'End status should be either "succeeded", "failed" or "aborted" (job id: %)', job_id;
END IF;
IF delete_job THEN
DELETE FROM procrastinate_jobs
WHERE id = job_id AND status IN ('todo', 'doing')
RETURNING id INTO _job_id;
ELSE
UPDATE procrastinate_jobs
SET status = end_status,
abort_requested = false,
result = job_result,
attempts = CASE status
WHEN 'doing' THEN attempts + 1 ELSE attempts
END
WHERE id = job_id AND status IN ('todo', 'doing')
RETURNING id INTO _job_id;
END IF;
IF _job_id IS NULL THEN
RAISE 'Job was not found or not in "doing" or "todo" status (job id: %)', job_id;
END IF;
END;
$$
4 changes: 3 additions & 1 deletion procrastinate/sql/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ CREATE TABLE procrastinate_jobs (
attempts integer DEFAULT 0 NOT NULL,
abort_requested boolean DEFAULT false NOT NULL,
worker_id bigint REFERENCES procrastinate_workers(id) ON DELETE SET NULL,
result text,
CONSTRAINT check_not_todo_abort_requested CHECK (NOT (status = 'todo' AND abort_requested = true))
);

Expand Down Expand Up @@ -245,7 +246,7 @@ BEGIN
END;
$$;

CREATE FUNCTION procrastinate_finish_job_v1(job_id bigint, end_status procrastinate_job_status, delete_job boolean)
CREATE FUNCTION procrastinate_finish_job_v1(job_id bigint, end_status procrastinate_job_status, delete_job boolean, job_result text default null)
RETURNS void
LANGUAGE plpgsql
AS $$
Expand All @@ -263,6 +264,7 @@ BEGIN
UPDATE procrastinate_jobs
SET status = end_status,
abort_requested = false,
result = job_result,
attempts = CASE status
WHEN 'doing' THEN attempts + 1 ELSE attempts
END
Expand Down
8 changes: 7 additions & 1 deletion procrastinate/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,13 @@ async def fetch_job_one(
self.events[job["id"]].append({"type": "started", "at": utils.utcnow()})
return job

async def finish_job_run(self, job_id: int, status: str, delete_job: bool) -> None:
async def finish_job_run(
self,
job_id: int,
status: str,
delete_job: bool,
exc_info: bool | BaseException = False,
) -> None:
if delete_job:
self.jobs.pop(job_id)
return
Expand Down
4 changes: 3 additions & 1 deletion procrastinate/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ async def _persist_job_status(
retry_decision: retry.RetryDecision | None,
context: job_context.JobContext,
job_result: job_context.JobResult | None,
exc_info: bool | BaseException = False,
):
if retry_decision:
await self.app.job_manager.retry_job(
Expand All @@ -156,7 +157,7 @@ async def _persist_job_status(
jobs.DeleteJobCondition.SUCCESSFUL: status == jobs.Status.SUCCEEDED,
}[self.delete_jobs]
await self.app.job_manager.finish_job(
job=job, status=status, delete_job=delete_job
job=job, status=status, delete_job=delete_job, exc_info=exc_info
)

assert job.id
Expand Down Expand Up @@ -314,6 +315,7 @@ async def ensure_async() -> Callable[..., Awaitable[Any]]:
retry_decision=retry_decision,
context=context,
job_result=job_result,
exc_info=exc_info,
)
)
try:
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ async def test_finish_job(job_manager, job_factory, connector):
)
assert connector.queries[-1] == (
"finish_job",
{"job_id": 1, "status": "succeeded", "delete_job": False},
{"job_id": 1, "status": "succeeded", "delete_job": False, "exc_info": None},
)


Expand All @@ -302,7 +302,7 @@ async def test_finish_job_with_deletion(job_manager, job_factory, connector):
await job_manager.finish_job(job=job, status=jobs.Status.SUCCEEDED, delete_job=True)
assert connector.queries[-1] == (
"finish_job",
{"job_id": 1, "status": "succeeded", "delete_job": True},
{"job_id": 1, "status": "succeeded", "delete_job": True, "exc_info": None},
)
assert 1 not in connector.jobs

Expand Down