Skip to content

Commit 62b4bc1

Browse files
committed
Fix #33302: allow to replace DelegateProxies
1 parent e52a242 commit 62b4bc1

2 files changed

Lines changed: 87 additions & 0 deletions

File tree

src/main/java/eu/openanalytics/containerproxy/backend/dispatcher/proxysharing/ProxySharingScaler.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import eu.openanalytics.containerproxy.event.PendingProxyEvent;
3131
import eu.openanalytics.containerproxy.event.ProxyStartFailedEvent;
3232
import eu.openanalytics.containerproxy.event.ProxyStopEvent;
33+
import eu.openanalytics.containerproxy.event.RemoveDelegateProxiesEvent;
3334
import eu.openanalytics.containerproxy.event.SeatAvailableEvent;
3435
import eu.openanalytics.containerproxy.event.SeatClaimedEvent;
3536
import eu.openanalytics.containerproxy.event.SeatReleasedEvent;
@@ -195,6 +196,26 @@ public void onProxyStartFailed(ProxyStartFailedEvent proxyStartFailedEvent) {
195196
pendingDelegatingProxies.remove(proxyStartFailedEvent.getProxyId());
196197
}
197198

199+
@EventListener
200+
public void onRemoveDelegateProxiesEvent(RemoveDelegateProxiesEvent event) {
201+
if ((event.getSpecId() != null && !Objects.equals(event.getSpecId(), proxySpec.getId()))
202+
|| !leaderService.isLeader()
203+
|| (event.getId() != null && delegateProxyStore.getDelegateProxy(event.getId()) == null)
204+
) {
205+
// only handle events for this spec
206+
return;
207+
}
208+
if (event.getId() != null) {
209+
// remove single proxy
210+
logger.info("[{} {}] Received external request to remove DelegateProxy", kv("specId", proxySpec.getId()), kv("delegateProxyId", event.getId()));
211+
globalEventLoop.schedule(() -> markDelegateProxyForRemoval(event.getId()));
212+
} else {
213+
// remove all proxies
214+
logger.info("[{}] Received external request to remove all DelegateProxies", kv("specId", proxySpec.getId()));
215+
globalEventLoop.schedule(this::markAllDelegateProxiesForRemoval);
216+
}
217+
}
218+
198219
/**
199220
* Processes the SeatReleasedEvent, should only process one event a a time (i.e. using the event loop),
200221
* since it modifies the Delegateproxy.
@@ -246,6 +267,9 @@ private void processReleasedSeat(SeatReleasedEvent seatReleasedEvent) {
246267
private void markDelegateProxyForRemoval(String delegateProxyId) {
247268
// this delegateProxy will be (completely) removed by the cleanup function, not by scale-down
248269
DelegateProxy delegateProxy = delegateProxyStore.getDelegateProxy(delegateProxyId);
270+
if (delegateProxy == null) {
271+
return;
272+
}
249273
Set<String> seatIds = delegateProxy.getSeatIds();
250274
DelegateProxy.DelegateProxyBuilder delegateProxyBuilder = delegateProxy.toBuilder()
251275
.delegateProxyStatus(DelegateProxyStatus.ToRemove);
@@ -267,6 +291,12 @@ private void markDelegateProxyForRemoval(String delegateProxyId) {
267291
delegateProxyStore.updateDelegateProxy(delegateProxyBuilder.build());
268292
}
269293

294+
private void markAllDelegateProxiesForRemoval() {
295+
for (DelegateProxy delegateProxy : delegateProxyStore.getAllDelegateProxies()) {
296+
markDelegateProxyForRemoval(delegateProxy.getProxy().getId());
297+
}
298+
}
299+
270300
private void reconcile() {
271301
long numPendingSeats = getNumPendingSeats();
272302
long num = seatStore.getNumUnclaimedSeats() + numPendingSeats - pendingDelegatingProxies.size();
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2024 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.event;
22+
23+
import com.fasterxml.jackson.annotation.JsonCreator;
24+
import com.fasterxml.jackson.annotation.JsonProperty;
25+
import lombok.AccessLevel;
26+
import lombok.EqualsAndHashCode;
27+
import lombok.NoArgsConstructor;
28+
import lombok.Value;
29+
30+
@Value
31+
@EqualsAndHashCode(callSuper = true)
32+
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE) // Jackson deserialize compatibility
33+
public class RemoveDelegateProxiesEvent extends BridgeableEvent {
34+
35+
String id;
36+
37+
String specId;
38+
39+
@JsonCreator
40+
public RemoveDelegateProxiesEvent(@JsonProperty("source") String source,
41+
@JsonProperty("id") String id,
42+
@JsonProperty("specId") String specId) {
43+
super(source);
44+
this.id = id;
45+
this.specId = specId;
46+
}
47+
48+
public RemoveDelegateProxiesEvent(String id, String specId) {
49+
this(SOURCE_NOT_AVAILABLE, id, specId);
50+
}
51+
52+
@Override
53+
public RemoveDelegateProxiesEvent withSource(String source) {
54+
return new RemoveDelegateProxiesEvent(source, id, specId);
55+
}
56+
57+
}

0 commit comments

Comments
 (0)