1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
/*
* Copyright (C) 2016, Google Inc. and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.ketch;
import java.util.Collection;
import java.util.Map;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.ReceiveCommand;
/**
* A push request sending objects to a replica, and its result.
* <p>
* Implementors of {@link org.eclipse.jgit.internal.ketch.KetchReplica} must
* populate the command result fields, {@link #setRefs(Map)}, and call one of
* {@link #setException(Repository, Throwable)} or {@link #done(Repository)} to
* finish processing.
*/
public class ReplicaPushRequest {
private final KetchReplica replica;
private final Collection<ReceiveCommand> commands;
private Map<String, Ref> refs;
private Throwable exception;
private boolean notified;
/**
* Construct a new push request for a replica.
*
* @param replica
* the replica being pushed to.
* @param commands
* commands to be executed.
*/
public ReplicaPushRequest(KetchReplica replica,
Collection<ReceiveCommand> commands) {
this.replica = replica;
this.commands = commands;
}
/**
* Get commands to be executed, and their results.
*
* @return commands to be executed, and their results.
*/
public Collection<ReceiveCommand> getCommands() {
return commands;
}
/**
* Get remote references, usually from the advertisement.
*
* @return remote references, usually from the advertisement.
*/
@Nullable
public Map<String, Ref> getRefs() {
return refs;
}
/**
* Set references observed from the replica.
*
* @param refs
* references observed from the replica.
*/
public void setRefs(Map<String, Ref> refs) {
this.refs = refs;
}
/**
* Get exception thrown, if any.
*
* @return exception thrown, if any.
*/
@Nullable
public Throwable getException() {
return exception;
}
/**
* Mark the request as crashing with a communication error.
* <p>
* This method may take significant time acquiring the leader lock and
* updating the Ketch state machine with the failure.
*
* @param repo
* local repository reference used by the push attempt.
* @param err
* exception thrown during communication.
*/
public void setException(@Nullable Repository repo, Throwable err) {
if (KetchReplica.log.isErrorEnabled()) {
KetchReplica.log.error(describe("failed"), err); //$NON-NLS-1$
}
if (!notified) {
notified = true;
exception = err;
replica.afterPush(repo, this);
}
}
/**
* Mark the request as completed without exception.
* <p>
* This method may take significant time acquiring the leader lock and
* updating the Ketch state machine with results from this replica.
*
* @param repo
* local repository reference used by the push attempt.
*/
public void done(Repository repo) {
if (KetchReplica.log.isDebugEnabled()) {
KetchReplica.log.debug(describe("completed")); //$NON-NLS-1$
}
if (!notified) {
notified = true;
replica.afterPush(repo, this);
}
}
private String describe(String heading) {
StringBuilder b = new StringBuilder();
b.append("push to "); //$NON-NLS-1$
b.append(replica.describeForLog());
b.append(' ').append(heading).append(":\n"); //$NON-NLS-1$
for (ReceiveCommand cmd : commands) {
b.append(String.format(
" %-12s %-12s %s %s", //$NON-NLS-1$
LeaderSnapshot.str(cmd.getOldId()),
LeaderSnapshot.str(cmd.getNewId()),
cmd.getRefName(),
cmd.getResult()));
if (cmd.getMessage() != null) {
b.append(' ').append(cmd.getMessage());
}
b.append('\n');
}
return b.toString();
}
}
|