]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Optimize account creation
authorChocobozzz <florian.bigard@gmail.com>
Thu, 16 Nov 2017 17:40:50 +0000 (18:40 +0100)
committerChocobozzz <florian.bigard@gmail.com>
Mon, 27 Nov 2017 18:40:52 +0000 (19:40 +0100)
scripts/parse-log.ts
server/controllers/api/users.ts
server/initializers/installer.ts
server/lib/user.ts
server/lib/video-channel.ts
server/models/account/account.ts
server/tests/api/config.ts
server/tests/utils/index.ts

index 81a22f7a0d3ba9b60d19e4c3ea50e322b72d157d..8aac6fbda704f0a60ad43024f2aad79d235834b5 100755 (executable)
@@ -38,5 +38,5 @@ const rl = createInterface({
 
 rl.on('line', line => {
   const log = JSON.parse(line)
-  logLevels[log.level](log.message)
+  logLevels[log.level](log.message, log.stack)
 })
index 41ffb64cb202868e878188f49d86ce562032b803..ac7c87517d8d0e9458f4c450edacba9d9aa433db 100644 (file)
@@ -70,7 +70,7 @@ usersRouter.post('/',
 usersRouter.post('/register',
   ensureUserRegistrationAllowed,
   usersRegisterValidator,
-  asyncMiddleware(registerUser)
+  asyncMiddleware(registerUserRetryWrapper)
 )
 
 usersRouter.put('/me',
@@ -113,7 +113,7 @@ async function getUserVideos (req: express.Request, res: express.Response, next:
 
 async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
   const options = {
-    arguments: [ req, res ],
+    arguments: [ req ],
     errorMessage: 'Cannot insert the user with many retries.'
   }
 
@@ -123,7 +123,7 @@ async function createUserRetryWrapper (req: express.Request, res: express.Respon
   return res.type('json').status(204).end()
 }
 
-async function createUser (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function createUser (req: express.Request) {
   const body: UserCreate = req.body
   const user = db.User.build({
     username: body.username,
@@ -139,7 +139,18 @@ async function createUser (req: express.Request, res: express.Response, next: ex
   logger.info('User %s with its channel and account created.', body.username)
 }
 
-async function registerUser (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function registerUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+  const options = {
+    arguments: [ req ],
+    errorMessage: 'Cannot insert the user with many retries.'
+  }
+
+  await retryTransactionWrapper(registerUser, options)
+
+  return res.type('json').status(204).end()
+}
+
+async function registerUser (req: express.Request) {
   const body: UserCreate = req.body
 
   const user = db.User.build({
@@ -152,7 +163,8 @@ async function registerUser (req: express.Request, res: express.Response, next:
   })
 
   await createUserAccountAndChannel(user)
-  return res.type('json').status(204).end()
+
+  logger.info('User %s with its channel and account registered.', body.username)
 }
 
 async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
index 3f4c4dfbbf5b0544dad9c6212b4afb385062a0b4..865495722feb71523380ac0ceab31ceb8708dde5 100644 (file)
@@ -2,10 +2,9 @@ import * as passwordGenerator from 'password-generator'
 import { UserRole } from '../../shared'
 import { logger, mkdirpPromise, rimrafPromise } from '../helpers'
 import { createUserAccountAndChannel } from '../lib'
-import { createLocalAccount } from '../lib/user'
+import { createLocalAccountWithoutKeys } from '../lib/user'
 import { applicationExist, clientsExist, usersExist } from './checker'
 import { CACHE, CONFIG, LAST_MIGRATION_VERSION, SERVER_ACCOUNT_NAME } from './constants'
-
 import { database as db } from './database'
 
 async function installApplication () {
@@ -136,5 +135,6 @@ async function createApplicationIfNotExist () {
   const applicationInstance = await db.Application.create({ migrationVersion: LAST_MIGRATION_VERSION })
 
   logger.info('Creating application account.')
-  return createLocalAccount(SERVER_ACCOUNT_NAME, null, applicationInstance.id, undefined)
+
+  return createLocalAccountWithoutKeys(SERVER_ACCOUNT_NAME, null, applicationInstance.id, undefined)
 }
index 9884e566f9f5ea0a69bd0db44dd0eb8f5322f125..2d7b36b4faae0e6dc380267ff78664db991df5c0 100644 (file)
@@ -5,16 +5,17 @@ import { database as db } from '../initializers'
 import { CONFIG } from '../initializers/constants'
 import { UserInstance } from '../models'
 import { createVideoChannel } from './video-channel'
+import { logger } from '../helpers/logger'
 
 async function createUserAccountAndChannel (user: UserInstance, validateUser = true) {
-  const res = await db.sequelize.transaction(async t => {
+  const { account, videoChannel } = await db.sequelize.transaction(async t => {
     const userOptions = {
       transaction: t,
       validate: validateUser
     }
 
     const userCreated = await user.save(userOptions)
-    const accountCreated = await createLocalAccount(user.username, user.id, null, t)
+    const accountCreated = await createLocalAccountWithoutKeys(user.username, user.id, null, t)
 
     const videoChannelName = `Default ${userCreated.username} channel`
     const videoChannelInfo = {
@@ -25,18 +26,23 @@ async function createUserAccountAndChannel (user: UserInstance, validateUser = t
     return { account: accountCreated, videoChannel }
   })
 
-  return res
+  // Set account keys, this could be long so process after the account creation and do not block the client
+  const { publicKey, privateKey } = await createPrivateAndPublicKeys()
+  account.set('publicKey', publicKey)
+  account.set('privateKey', privateKey)
+  account.save().catch(err => logger.error('Cannot set public/private keys of local account %d.', account.id, err))
+
+  return { account, videoChannel }
 }
 
-async function createLocalAccount (name: string, userId: number, applicationId: number, t: Sequelize.Transaction) {
-  const { publicKey, privateKey } = await createPrivateAndPublicKeys()
+async function createLocalAccountWithoutKeys (name: string, userId: number, applicationId: number, t: Sequelize.Transaction) {
   const url = getActivityPubUrl('account', name)
 
   const accountInstance = db.Account.build({
     name,
     url,
-    publicKey,
-    privateKey,
+    publicKey: null,
+    privateKey: null,
     followersCount: 0,
     followingCount: 0,
     inboxUrl: url + '/inbox',
@@ -56,5 +62,5 @@ async function createLocalAccount (name: string, userId: number, applicationId:
 
 export {
   createUserAccountAndChannel,
-  createLocalAccount
+  createLocalAccountWithoutKeys
 }
index e69ec062f2ad7bd442de775826570991f51f78d2..6f9ae2d95472fe06b5cd163a2c026db18de3b081 100644 (file)
@@ -25,9 +25,7 @@ async function createVideoChannel (videoChannelInfo: VideoChannelCreate, account
   // Do not forget to add Account information to the created video channel
   videoChannelCreated.Account = account
 
-  await sendCreateVideoChannel(videoChannelCreated, t)
-  await shareVideoChannelByServer(videoChannelCreated, t)
-
+  // No need to seed this empty video channel to followers
   return videoChannelCreated
 }
 
index 84461a2eb481be098591d5569a1a77ece95a2de0..c370e17096cb90c6f8e49ffb5d0c64faeb035411 100644 (file)
@@ -75,7 +75,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
       },
       publicKey: {
         type: DataTypes.STRING(CONSTRAINTS_FIELDS.ACCOUNTS.PUBLIC_KEY.max),
-        allowNull: false,
+        allowNull: true,
         validate: {
           publicKeyValid: value => {
             const res = isAccountPublicKeyValid(value)
index 3dda3b4d7fe3704f25e6d521d101bedb1fc185f5..72a9e5679f310e15100df1d43f8e2bd206c19d29 100644 (file)
@@ -15,7 +15,7 @@ describe('Test config', function () {
   let server = null
 
   before(async function () {
-    this.timeout(120000)
+    this.timeout(10000)
 
     await flushTests()
     server = await runServer(1)
@@ -29,9 +29,11 @@ describe('Test config', function () {
   })
 
   it('Should have a correct config on a server with registration enabled and a users limit', async function () {
-    await registerUser(server.url, 'user1', 'super password')
-    await registerUser(server.url, 'user2', 'super password')
-    await registerUser(server.url, 'user3', 'super password')
+    await Promise.all([
+      registerUser(server.url, 'user1', 'super password'),
+      registerUser(server.url, 'user2', 'super password'),
+      registerUser(server.url, 'user3', 'super password')
+    ])
 
     const res = await getConfig(server.url)
     const data = res.body
index 4325e4c941b41bb3871883ba76facd0eb1ff5248..fe6d3b0412eae826002970ef0ffa273bb8ec46a8 100644 (file)
@@ -3,7 +3,7 @@ export * from './clients'
 export * from './config'
 export * from './login'
 export * from './miscs'
-export * from './pods'
+export * from './follows'
 export * from './request-schedulers'
 export * from './requests'
 export * from './servers'