aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-02-14 08:59:27 +0100
committerChocobozzz <me@florianbigard.com>2023-02-14 09:03:22 +0100
commit4565774669bc3c1b11cc726d577946953dbe53c5 (patch)
treeee0e41e06245861a0de896684caa388f82cc3470 /server
parent4c61660a0ab6224079c67d8282b282772a0772e4 (diff)
downloadPeerTube-4565774669bc3c1b11cc726d577946953dbe53c5.tar.gz
PeerTube-4565774669bc3c1b11cc726d577946953dbe53c5.tar.zst
PeerTube-4565774669bc3c1b11cc726d577946953dbe53c5.zip
Fix retrying update on sql serialization conflict
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/video-channel.ts6
-rw-r--r--server/controllers/api/video-playlist.ts6
-rw-r--r--server/controllers/api/videos/update.ts6
-rw-r--r--server/helpers/database-utils.ts6
-rw-r--r--server/lib/activitypub/actors/updater.ts15
-rw-r--r--server/lib/activitypub/videos/updater.ts8
6 files changed, 14 insertions, 33 deletions
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts
index d7c92952a..5b9fb794a 100644
--- a/server/controllers/api/video-channel.ts
+++ b/server/controllers/api/video-channel.ts
@@ -273,7 +273,6 @@ async function addVideoChannel (req: express.Request, res: express.Response) {
273 273
274async function updateVideoChannel (req: express.Request, res: express.Response) { 274async function updateVideoChannel (req: express.Request, res: express.Response) {
275 const videoChannelInstance = res.locals.videoChannel 275 const videoChannelInstance = res.locals.videoChannel
276 const videoChannelFieldsSave = videoChannelInstance.toJSON()
277 const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannelInstance.toFormattedJSON()) 276 const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannelInstance.toFormattedJSON())
278 const videoChannelInfoToUpdate = req.body as VideoChannelUpdate 277 const videoChannelInfoToUpdate = req.body as VideoChannelUpdate
279 let doBulkVideoUpdate = false 278 let doBulkVideoUpdate = false
@@ -309,10 +308,9 @@ async function updateVideoChannel (req: express.Request, res: express.Response)
309 } catch (err) { 308 } catch (err) {
310 logger.debug('Cannot update the video channel.', { err }) 309 logger.debug('Cannot update the video channel.', { err })
311 310
312 // Force fields we want to update
313 // If the transaction is retried, sequelize will think the object has not changed 311 // If the transaction is retried, sequelize will think the object has not changed
314 // So it will skip the SQL request, even if the last one was ROLLBACKed! 312 // So we need to restore the previous fields
315 resetSequelizeInstance(videoChannelInstance, videoChannelFieldsSave) 313 resetSequelizeInstance(videoChannelInstance)
316 314
317 throw err 315 throw err
318 } 316 }
diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts
index 947f7ca77..bcb60e265 100644
--- a/server/controllers/api/video-playlist.ts
+++ b/server/controllers/api/video-playlist.ts
@@ -210,7 +210,6 @@ async function addVideoPlaylist (req: express.Request, res: express.Response) {
210 210
211async function updateVideoPlaylist (req: express.Request, res: express.Response) { 211async function updateVideoPlaylist (req: express.Request, res: express.Response) {
212 const videoPlaylistInstance = res.locals.videoPlaylistFull 212 const videoPlaylistInstance = res.locals.videoPlaylistFull
213 const videoPlaylistFieldsSave = videoPlaylistInstance.toJSON()
214 const videoPlaylistInfoToUpdate = req.body as VideoPlaylistUpdate 213 const videoPlaylistInfoToUpdate = req.body as VideoPlaylistUpdate
215 214
216 const wasPrivatePlaylist = videoPlaylistInstance.privacy === VideoPlaylistPrivacy.PRIVATE 215 const wasPrivatePlaylist = videoPlaylistInstance.privacy === VideoPlaylistPrivacy.PRIVATE
@@ -275,10 +274,9 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response)
275 } catch (err) { 274 } catch (err) {
276 logger.debug('Cannot update the video playlist.', { err }) 275 logger.debug('Cannot update the video playlist.', { err })
277 276
278 // Force fields we want to update
279 // If the transaction is retried, sequelize will think the object has not changed 277 // If the transaction is retried, sequelize will think the object has not changed
280 // So it will skip the SQL request, even if the last one was ROLLBACKed! 278 // So we need to restore the previous fields
281 resetSequelizeInstance(videoPlaylistInstance, videoPlaylistFieldsSave) 279 resetSequelizeInstance(videoPlaylistInstance)
282 280
283 throw err 281 throw err
284 } 282 }
diff --git a/server/controllers/api/videos/update.ts b/server/controllers/api/videos/update.ts
index 260dee2b9..e6197c4b1 100644
--- a/server/controllers/api/videos/update.ts
+++ b/server/controllers/api/videos/update.ts
@@ -45,7 +45,6 @@ export {
45 45
46async function updateVideo (req: express.Request, res: express.Response) { 46async function updateVideo (req: express.Request, res: express.Response) {
47 const videoFromReq = res.locals.videoAll 47 const videoFromReq = res.locals.videoAll
48 const videoFieldsSave = videoFromReq.toJSON()
49 const oldVideoAuditView = new VideoAuditView(videoFromReq.toFormattedDetailsJSON()) 48 const oldVideoAuditView = new VideoAuditView(videoFromReq.toFormattedDetailsJSON())
50 const videoInfoToUpdate: VideoUpdate = req.body 49 const videoInfoToUpdate: VideoUpdate = req.body
51 50
@@ -151,10 +150,9 @@ async function updateVideo (req: express.Request, res: express.Response) {
151 isNewVideo 150 isNewVideo
152 }) 151 })
153 } catch (err) { 152 } catch (err) {
154 // Force fields we want to update
155 // If the transaction is retried, sequelize will think the object has not changed 153 // If the transaction is retried, sequelize will think the object has not changed
156 // So it will skip the SQL request, even if the last one was ROLLBACKed! 154 // So we need to restore the previous fields
157 resetSequelizeInstance(videoFromReq, videoFieldsSave) 155 resetSequelizeInstance(videoFromReq)
158 156
159 throw err 157 throw err
160 } finally { 158 } finally {
diff --git a/server/helpers/database-utils.ts b/server/helpers/database-utils.ts
index 627381086..0e6b35503 100644
--- a/server/helpers/database-utils.ts
+++ b/server/helpers/database-utils.ts
@@ -78,10 +78,8 @@ function updateInstanceWithAnother <M, T extends U, U extends Model<M>> (instanc
78 } 78 }
79} 79}
80 80
81function resetSequelizeInstance (instance: Model<any>, savedFields: object) { 81function resetSequelizeInstance <T> (instance: Model<T>) {
82 Object.keys(savedFields).forEach(key => { 82 instance.set(instance.previous())
83 instance[key] = savedFields[key]
84 })
85} 83}
86 84
87function filterNonExistingModels <T extends { hasSameUniqueKeysThan (other: T): boolean }> ( 85function filterNonExistingModels <T extends { hasSameUniqueKeysThan (other: T): boolean }> (
diff --git a/server/lib/activitypub/actors/updater.ts b/server/lib/activitypub/actors/updater.ts
index fe94af9f1..137980460 100644
--- a/server/lib/activitypub/actors/updater.ts
+++ b/server/lib/activitypub/actors/updater.ts
@@ -13,19 +13,12 @@ export class APActorUpdater {
13 13
14 private accountOrChannel: MAccount | MChannel 14 private accountOrChannel: MAccount | MChannel
15 15
16 private readonly actorFieldsSave: object
17 private readonly accountOrChannelFieldsSave: object
18
19 constructor ( 16 constructor (
20 private readonly actorObject: ActivityPubActor, 17 private readonly actorObject: ActivityPubActor,
21 private readonly actor: MActorFull 18 private readonly actor: MActorFull
22 ) { 19 ) {
23 this.actorFieldsSave = this.actor.toJSON()
24
25 if (this.actorObject.type === 'Group') this.accountOrChannel = this.actor.VideoChannel 20 if (this.actorObject.type === 'Group') this.accountOrChannel = this.actor.VideoChannel
26 else this.accountOrChannel = this.actor.Account 21 else this.accountOrChannel = this.actor.Account
27
28 this.accountOrChannelFieldsSave = this.accountOrChannel.toJSON()
29 } 22 }
30 23
31 async update () { 24 async update () {
@@ -58,12 +51,12 @@ export class APActorUpdater {
58 51
59 logger.info('Remote account %s updated', this.actorObject.url) 52 logger.info('Remote account %s updated', this.actorObject.url)
60 } catch (err) { 53 } catch (err) {
61 if (this.actor !== undefined && this.actorFieldsSave !== undefined) { 54 if (this.actor !== undefined) {
62 resetSequelizeInstance(this.actor, this.actorFieldsSave) 55 resetSequelizeInstance(this.actor)
63 } 56 }
64 57
65 if (this.accountOrChannel !== undefined && this.accountOrChannelFieldsSave !== undefined) { 58 if (this.accountOrChannel !== undefined) {
66 resetSequelizeInstance(this.accountOrChannel, this.accountOrChannelFieldsSave) 59 resetSequelizeInstance(this.accountOrChannel)
67 } 60 }
68 61
69 // This is just a debug because we will retry the insert 62 // This is just a debug because we will retry the insert
diff --git a/server/lib/activitypub/videos/updater.ts b/server/lib/activitypub/videos/updater.ts
index 32cbf7e07..0bf32f440 100644
--- a/server/lib/activitypub/videos/updater.ts
+++ b/server/lib/activitypub/videos/updater.ts
@@ -13,8 +13,6 @@ export class APVideoUpdater extends APVideoAbstractBuilder {
13 private readonly wasPrivateVideo: boolean 13 private readonly wasPrivateVideo: boolean
14 private readonly wasUnlistedVideo: boolean 14 private readonly wasUnlistedVideo: boolean
15 15
16 private readonly videoFieldsSave: any
17
18 private readonly oldVideoChannel: MChannelAccountLight 16 private readonly oldVideoChannel: MChannelAccountLight
19 17
20 protected lTags: LoggerTagsFn 18 protected lTags: LoggerTagsFn
@@ -30,8 +28,6 @@ export class APVideoUpdater extends APVideoAbstractBuilder {
30 28
31 this.oldVideoChannel = this.video.VideoChannel 29 this.oldVideoChannel = this.video.VideoChannel
32 30
33 this.videoFieldsSave = this.video.toJSON()
34
35 this.lTags = loggerTagsFactory('ap', 'video', 'update', video.uuid, video.url) 31 this.lTags = loggerTagsFactory('ap', 'video', 'update', video.uuid, video.url)
36 } 32 }
37 33
@@ -156,8 +152,8 @@ export class APVideoUpdater extends APVideoAbstractBuilder {
156 } 152 }
157 153
158 private catchUpdateError (err: Error) { 154 private catchUpdateError (err: Error) {
159 if (this.video !== undefined && this.videoFieldsSave !== undefined) { 155 if (this.video !== undefined) {
160 resetSequelizeInstance(this.video, this.videoFieldsSave) 156 resetSequelizeInstance(this.video)
161 } 157 }
162 158
163 // This is just a debug because we will retry the insert 159 // This is just a debug because we will retry the insert