Remove duplicated videos on unfollow/delete redundancy

This commit is contained in:
Chocobozzz 2018-09-28 10:07:05 +02:00
parent d0b52b5285
commit 161b061d4e
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
7 changed files with 115 additions and 17 deletions

View File

@ -1,4 +1,4 @@
$icon-font-path: '../../node_modules/@neos21/bootstrap3-glyphicons/assets/fonts/'; $icon-font-path: '~@neos21/bootstrap3-glyphicons/assets/fonts/';
@import '_bootstrap'; @import '_bootstrap';
@import '_variables'; @import '_variables';

View File

@ -1,4 +1,4 @@
$FontPathSourceSansPro: '../../node_modules/npm-font-source-sans-pro/fonts'; $FontPathSourceSansPro: '~npm-font-source-sans-pro/fonts';
@font-face { @font-face {
font-family: 'Source Sans Pro'; font-family: 'Source Sans Pro';

View File

@ -17,6 +17,7 @@ import {
import { followersSortValidator, followingSortValidator, followValidator } from '../../../middlewares/validators' import { followersSortValidator, followingSortValidator, followValidator } from '../../../middlewares/validators'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow' import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { JobQueue } from '../../../lib/job-queue' import { JobQueue } from '../../../lib/job-queue'
import { removeRedundancyOf } from '../../../lib/redundancy'
const serverFollowsRouter = express.Router() const serverFollowsRouter = express.Router()
serverFollowsRouter.get('/following', serverFollowsRouter.get('/following',
@ -101,6 +102,10 @@ async function removeFollow (req: express.Request, res: express.Response, next:
server.redundancyAllowed = false server.redundancyAllowed = false
await server.save({ transaction: t }) await server.save({ transaction: t })
// Async, could be long
removeRedundancyOf(server.id)
.catch(err => logger.error('Cannot remove redundancy of %s.', server.host, err))
await follow.destroy({ transaction: t }) await follow.destroy({ transaction: t })
}) })

View File

@ -3,6 +3,8 @@ import { UserRight } from '../../../../shared/models/users'
import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares' import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares'
import { updateServerRedundancyValidator } from '../../../middlewares/validators/redundancy' import { updateServerRedundancyValidator } from '../../../middlewares/validators/redundancy'
import { ServerModel } from '../../../models/server/server' import { ServerModel } from '../../../models/server/server'
import { removeRedundancyOf } from '../../../lib/redundancy'
import { logger } from '../../../helpers/logger'
const serverRedundancyRouter = express.Router() const serverRedundancyRouter = express.Router()
@ -28,5 +30,9 @@ async function updateRedundancy (req: express.Request, res: express.Response, ne
await server.save() await server.save()
// Async, could be long
removeRedundancyOf(server.id)
.catch(err => logger.error('Cannot remove redundancy of %s.', server.host, err))
return res.sendStatus(204) return res.sendStatus(204)
} }

View File

@ -12,8 +12,17 @@ async function removeVideoRedundancy (videoRedundancy: VideoRedundancyModel, t?:
await videoRedundancy.destroy({ transaction: t }) await videoRedundancy.destroy({ transaction: t })
} }
async function removeRedundancyOf (serverId: number) {
const videosRedundancy = await VideoRedundancyModel.listLocalOfServer(serverId)
for (const redundancy of videosRedundancy) {
await removeVideoRedundancy(redundancy)
}
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export { export {
removeRedundancyOf,
removeVideoRedundancy removeVideoRedundancy
} }

View File

@ -286,6 +286,47 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
return VideoRedundancyModel.scope([ ScopeNames.WITH_VIDEO ]).findAll(query) return VideoRedundancyModel.scope([ ScopeNames.WITH_VIDEO ]).findAll(query)
} }
static async listLocalOfServer (serverId: number) {
const actor = await getServerActor()
const query = {
where: {
actorId: actor.id
},
include: [
{
model: VideoFileModel,
required: true,
include: [
{
model: VideoModel,
required: true,
include: [
{
attributes: [],
model: VideoChannelModel.unscoped(),
required: true,
include: [
{
attributes: [],
model: ActorModel.unscoped(),
required: true,
where: {
serverId
}
}
]
}
]
}
]
}
]
}
return VideoRedundancyModel.findAll(query)
}
static async getStats (strategy: VideoRedundancyStrategy) { static async getStats (strategy: VideoRedundancyStrategy) {
const actor = await getServerActor() const actor = await getServerActor()

View File

@ -12,7 +12,7 @@ import {
killallServers, makeGetRequest, killallServers, makeGetRequest,
root, root,
ServerInfo, ServerInfo,
setAccessTokensToServers, setAccessTokensToServers, unfollow,
uploadVideo, uploadVideo,
viewVideo, viewVideo,
wait wait
@ -39,6 +39,8 @@ function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: numbe
const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`) const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`)
expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined
} }
expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length)
} }
async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) { async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) {
@ -136,23 +138,21 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
] ]
for (const server of servers) { for (const server of servers) {
{ const res = await getVideo(server.url, videoUUID)
const res = await getVideo(server.url, videoUUID)
const video: VideoDetails = res.body const video: VideoDetails = res.body
for (const file of video.files) { for (const file of video.files) {
checkMagnetWebseeds(file, webseeds, server) checkMagnetWebseeds(file, webseeds, server)
// Only servers 1 and 2 have the video // Only servers 1 and 2 have the video
if (server.serverNumber !== 3) { if (server.serverNumber !== 3) {
await makeGetRequest({ await makeGetRequest({
url: server.url, url: server.url,
statusCodeExpected: 200, statusCodeExpected: 200,
path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`, path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`,
contentType: null contentType: null
}) })
}
} }
} }
} }
@ -182,6 +182,21 @@ async function enableRedundancyOnServer1 () {
expect(server2.following.hostRedundancyAllowed).to.be.true expect(server2.following.hostRedundancyAllowed).to.be.true
} }
async function disableRedundancyOnServer1 () {
await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, false)
const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt')
const follows: ActorFollow[] = res.body.data
const server2 = follows.find(f => f.following.host === 'localhost:9002')
const server3 = follows.find(f => f.following.host === 'localhost:9003')
expect(server3).to.not.be.undefined
expect(server3.following.hostRedundancyAllowed).to.be.false
expect(server2).to.not.be.undefined
expect(server2.following.hostRedundancyAllowed).to.be.false
}
async function cleanServers () { async function cleanServers () {
killallServers(servers) killallServers(servers)
} }
@ -217,6 +232,17 @@ describe('Test videos redundancy', function () {
await checkStatsWith2Webseed(strategy) await checkStatsWith2Webseed(strategy)
}) })
it('Should undo redundancy on server 1 and remove duplicated videos', async function () {
this.timeout(40000)
await disableRedundancyOnServer1()
await waitJobs(servers)
await wait(5000)
await check1WebSeed(strategy)
})
after(function () { after(function () {
return cleanServers() return cleanServers()
}) })
@ -251,6 +277,17 @@ describe('Test videos redundancy', function () {
await checkStatsWith2Webseed(strategy) await checkStatsWith2Webseed(strategy)
}) })
it('Should unfollow on server 1 and remove duplicated videos', async function () {
this.timeout(40000)
await unfollow(servers[0].url, servers[0].accessToken, servers[1])
await waitJobs(servers)
await wait(5000)
await check1WebSeed(strategy)
})
after(function () { after(function () {
return cleanServers() return cleanServers()
}) })