From 5350fd8e5b2b2d017b16d97828893a8a4a40bd89 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 18 Apr 2018 15:32:40 +0200 Subject: Move server follow in the job queue It helps to track follow errors --- .../lib/job-queue/handlers/activitypub-follow.ts | 68 ++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 server/lib/job-queue/handlers/activitypub-follow.ts (limited to 'server/lib/job-queue/handlers/activitypub-follow.ts') diff --git a/server/lib/job-queue/handlers/activitypub-follow.ts b/server/lib/job-queue/handlers/activitypub-follow.ts new file mode 100644 index 000000000..6764a4037 --- /dev/null +++ b/server/lib/job-queue/handlers/activitypub-follow.ts @@ -0,0 +1,68 @@ +import * as kue from 'kue' +import { logger } from '../../../helpers/logger' +import { getServerActor } from '../../../helpers/utils' +import { REMOTE_SCHEME, sequelizeTypescript, SERVER_ACTOR_NAME } from '../../../initializers' +import { sendFollow } from '../../activitypub/send' +import { sanitizeHost } from '../../../helpers/core-utils' +import { loadActorUrlOrGetFromWebfinger } from '../../../helpers/webfinger' +import { getOrCreateActorAndServerAndModel } from '../../activitypub/actor' +import { retryTransactionWrapper } from '../../../helpers/database-utils' +import { ActorFollowModel } from '../../../models/activitypub/actor-follow' +import { ActorModel } from '../../../models/activitypub/actor' + +export type ActivitypubFollowPayload = { + host: string +} + +async function processActivityPubFollow (job: kue.Job) { + const payload = job.data as ActivitypubFollowPayload + const host = payload.host + + logger.info('Processing ActivityPub follow in job %d.', job.id) + + const sanitizedHost = sanitizeHost(host, REMOTE_SCHEME.HTTP) + + const actorUrl = await loadActorUrlOrGetFromWebfinger(SERVER_ACTOR_NAME, sanitizedHost) + const targetActor = await getOrCreateActorAndServerAndModel(actorUrl) + + const fromActor = await getServerActor() + const options = { + arguments: [ fromActor, targetActor ], + errorMessage: 'Cannot follow with many retries.' + } + + return retryTransactionWrapper(follow, options) +} +// --------------------------------------------------------------------------- + +export { + processActivityPubFollow +} + +// --------------------------------------------------------------------------- + +function follow (fromActor: ActorModel, targetActor: ActorModel) { + if (fromActor.id === targetActor.id) { + throw new Error('Follower is the same than target actor.') + } + + return sequelizeTypescript.transaction(async t => { + const [ actorFollow ] = await ActorFollowModel.findOrCreate({ + where: { + actorId: fromActor.id, + targetActorId: targetActor.id + }, + defaults: { + state: 'pending', + actorId: fromActor.id, + targetActorId: targetActor.id + }, + transaction: t + }) + actorFollow.ActorFollowing = targetActor + actorFollow.ActorFollower = fromActor + + // Send a notification to remote server + await sendFollow(actorFollow) + }) +} -- cgit v1.2.3