LCOV - code coverage report
Current view: top level - server/schema - Schema_185.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 42 49 85.7 %
Date: 2022-11-19 15:00:39 Functions: 8 8 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2022 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.server.schema;
      16             : 
      17             : import com.google.common.base.Stopwatch;
      18             : import com.google.common.collect.Iterables;
      19             : import com.google.common.collect.Sets;
      20             : import com.google.gerrit.entities.Project;
      21             : import com.google.gerrit.server.git.GitRepositoryManager;
      22             : import com.google.gerrit.server.project.ProjectConfig;
      23             : import java.io.IOException;
      24             : import java.io.UncheckedIOException;
      25             : import java.util.List;
      26             : import java.util.NavigableSet;
      27             : import java.util.Set;
      28             : import java.util.concurrent.ExecutorService;
      29             : import java.util.concurrent.Executors;
      30             : import java.util.concurrent.Future;
      31             : import java.util.concurrent.TimeUnit;
      32             : import java.util.concurrent.atomic.AtomicInteger;
      33             : import org.eclipse.jgit.errors.ConfigInvalidException;
      34             : import org.eclipse.jgit.lib.PersonIdent;
      35             : 
      36             : /**
      37             :  * Migrates the label configurations of all projects to copy conditions.
      38             :  *
      39             :  * @see MigrateLabelConfigToCopyCondition
      40             :  */
      41           2 : public class Schema_185 implements NoteDbSchemaVersion {
      42           2 :   private AtomicInteger i = new AtomicInteger();
      43           2 :   private Stopwatch sw = Stopwatch.createStarted();
      44             :   private int size;
      45             : 
      46             :   @Override
      47             :   public void upgrade(Arguments args, UpdateUI ui) throws Exception {
      48           1 :     ui.message("Migrating label configurations");
      49             : 
      50           1 :     NavigableSet<Project.NameKey> projects = args.repoManager.list();
      51           1 :     size = projects.size();
      52             : 
      53           1 :     Set<List<Project.NameKey>> batches = Sets.newHashSet(Iterables.partition(projects, 50));
      54           1 :     ExecutorService pool = createExecutor(ui);
      55             :     try {
      56           1 :       batches.stream()
      57           1 :           .forEach(
      58             :               batch -> {
      59             :                 @SuppressWarnings("unused")
      60           1 :                 Future<?> possiblyIgnoredError =
      61           1 :                     pool.submit(() -> processBatch(args.repoManager, args.serverUser, batch, ui));
      62           1 :               });
      63           1 :       pool.shutdown();
      64           1 :       pool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
      65           0 :     } catch (InterruptedException e) {
      66           0 :       throw new RuntimeException(e);
      67           1 :     }
      68           1 :     ui.message(
      69           1 :         String.format(
      70             :             "... (%.3f s) Migrated label configurations of all %d projects to schema 185",
      71           1 :             elapsed(), i.get()));
      72           1 :   }
      73             : 
      74             :   private ExecutorService createExecutor(UpdateUI ui) {
      75             :     int threads;
      76             :     try {
      77           0 :       threads = Integer.parseInt(System.getProperty("threadcount"));
      78           1 :     } catch (NumberFormatException e) {
      79           1 :       threads = Runtime.getRuntime().availableProcessors();
      80           0 :     }
      81           1 :     ui.message(String.format("... using %d threads ...", threads));
      82           1 :     return Executors.newFixedThreadPool(threads);
      83             :   }
      84             : 
      85             :   private void processBatch(
      86             :       GitRepositoryManager repoManager,
      87             :       PersonIdent serverUser,
      88             :       List<Project.NameKey> batch,
      89             :       UpdateUI ui) {
      90             :     try {
      91           1 :       for (Project.NameKey project : batch) {
      92             :         try {
      93           1 :           new MigrateLabelConfigToCopyCondition(repoManager, serverUser).execute(project);
      94           1 :           int count = i.incrementAndGet();
      95           1 :           showProgress(ui, count);
      96           1 :         } catch (ConfigInvalidException e) {
      97           1 :           ui.message(
      98           1 :               String.format(
      99             :                   "WARNING: Skipping migration of label configurations for project %s"
     100             :                       + " since its %s file is invalid: %s",
     101           1 :                   project, ProjectConfig.PROJECT_CONFIG, e.getMessage()));
     102           1 :         }
     103           1 :       }
     104           0 :     } catch (IOException e) {
     105           0 :       throw new UncheckedIOException(
     106           0 :           String.format("Failed to migrate batch of projects to schema 185: %s", batch), e);
     107           1 :     }
     108           1 :   }
     109             : 
     110             :   private double elapsed() {
     111           1 :     return sw.elapsed(TimeUnit.MILLISECONDS) / 1000d;
     112             :   }
     113             : 
     114             :   private void showProgress(UpdateUI ui, int count) {
     115           1 :     if (count % 100 == 0) {
     116           1 :       ui.message(
     117           1 :           String.format(
     118             :               "... (%.3f s) migrated label configurations of %d%% (%d/%d) projects",
     119           1 :               elapsed(), Math.round(100.0 * count / size), count, size));
     120             :     }
     121           1 :   }
     122             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750