You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

KetchLeaderCache.java 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright (C) 2016, Google Inc. and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.internal.ketch;
  11. import java.net.URISyntaxException;
  12. import java.util.concurrent.ConcurrentHashMap;
  13. import java.util.concurrent.ConcurrentMap;
  14. import java.util.concurrent.locks.Lock;
  15. import java.util.concurrent.locks.ReentrantLock;
  16. import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
  17. import org.eclipse.jgit.lib.Repository;
  18. /**
  19. * A cache of live leader instances, keyed by repository.
  20. * <p>
  21. * Ketch only assigns a leader to a repository when needed. If
  22. * {@link #get(Repository)} is called for a repository that does not have a
  23. * leader, the leader is created and added to the cache.
  24. */
  25. public class KetchLeaderCache {
  26. private final KetchSystem system;
  27. private final ConcurrentMap<String, KetchLeader> leaders;
  28. private final Lock startLock;
  29. /**
  30. * Initialize a new leader cache.
  31. *
  32. * @param system
  33. * system configuration for the leaders
  34. */
  35. public KetchLeaderCache(KetchSystem system) {
  36. this.system = system;
  37. leaders = new ConcurrentHashMap<>();
  38. startLock = new ReentrantLock(true /* fair */);
  39. }
  40. /**
  41. * Lookup the leader instance for a given repository.
  42. *
  43. * @param repo
  44. * repository to get the leader for.
  45. * @return the leader instance for the repository.
  46. * @throws java.net.URISyntaxException
  47. * remote configuration contains an invalid URL.
  48. */
  49. public KetchLeader get(Repository repo)
  50. throws URISyntaxException {
  51. String key = computeKey(repo);
  52. KetchLeader leader = leaders.get(key);
  53. if (leader != null) {
  54. return leader;
  55. }
  56. return startLeader(key, repo);
  57. }
  58. private KetchLeader startLeader(String key, Repository repo)
  59. throws URISyntaxException {
  60. startLock.lock();
  61. try {
  62. KetchLeader leader = leaders.get(key);
  63. if (leader != null) {
  64. return leader;
  65. }
  66. leader = system.createLeader(repo);
  67. leaders.put(key, leader);
  68. return leader;
  69. } finally {
  70. startLock.unlock();
  71. }
  72. }
  73. private static String computeKey(Repository repo) {
  74. if (repo instanceof DfsRepository) {
  75. DfsRepository dfs = (DfsRepository) repo;
  76. return dfs.getDescription().getRepositoryName();
  77. }
  78. if (repo.getDirectory() != null) {
  79. return repo.getDirectory().toURI().toString();
  80. }
  81. throw new IllegalArgumentException();
  82. }
  83. }