All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hudi.timeline.service.handlers.InstantStateHandler Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hudi.timeline.service.handlers;

import org.apache.hudi.common.table.timeline.dto.InstantStateDTO;
import org.apache.hudi.common.table.view.FileSystemViewManager;
import org.apache.hudi.exception.HoodieIOException;
import org.apache.hudi.storage.HoodieStorage;
import org.apache.hudi.storage.StorageConfiguration;
import org.apache.hudi.storage.StoragePath;
import org.apache.hudi.timeline.service.TimelineService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * REST Handler servicing instant state requests.
 * 

* The instant states are cached in timeline server and will be refreshed after the instant states in file system were changed. */ public class InstantStateHandler extends Handler { private static final Logger LOG = LoggerFactory.getLogger(InstantStateHandler.class); /** * Base url for instant state requests. */ private static final String BASE_URL = "/v1/hoodie/instantstate"; /** * Param for instant state requests, which contains a uniqueId for different writers. */ public static final String INSTANT_STATE_DIR_PATH_PARAM = "instantstatedirpath"; /** * GET requests. Returns all the instant states under instant state path. */ public static final String ALL_INSTANT_STATE_URL = String.format("%s/%s", BASE_URL, "all"); /** * POST requests. Refresh the instant state data cached in memory. */ public static final String REFRESH_INSTANT_STATE = String.format("%s/%s", BASE_URL, "refresh/"); /** * Cached instant state data, instant state path -> list of instant states in fs. */ private final ConcurrentHashMap> cachedInstantStates; /** * Number of requests after the last refresh. */ private final AtomicLong requestCount; public InstantStateHandler(StorageConfiguration conf, TimelineService.Config timelineServiceConfig, HoodieStorage storage, FileSystemViewManager viewManager) throws IOException { super(conf, timelineServiceConfig, storage, viewManager); this.cachedInstantStates = new ConcurrentHashMap<>(); this.requestCount = new AtomicLong(); } /** * Read instant states from cache of file system. * * @return Instant states under the input instant state path. */ public List getAllInstantStates(String instantStatePath) { if (requestCount.incrementAndGet() >= timelineServiceConfig.instantStateForceRefreshRequestNumber) { // Do refresh for every N requests to ensure the writers won't be blocked forever refresh(instantStatePath); } return cachedInstantStates.computeIfAbsent(instantStatePath, k -> scanInstantState(new StoragePath(k))); } /** * Refresh the checkpoint messages cached. Will be called when coordinator start/commit/abort instant. * * @return Whether refreshing is successful. */ public boolean refresh(String instantStatePath) { try { cachedInstantStates.put(instantStatePath, scanInstantState(new StoragePath(instantStatePath))); requestCount.set(0); } catch (Exception e) { LOG.error("Failed to load instant states, path: " + instantStatePath, e); return false; } return true; } /** * Scan the instant states from file system. */ public List scanInstantState(StoragePath instantStatePath) { try { // Check instantStatePath exists before list status, see HUDI-5915 if (this.storage.exists(instantStatePath)) { return this.storage.listDirectEntries(instantStatePath).stream() .map(InstantStateDTO::fromStoragePathInfo).collect(Collectors.toList()); } else { return Collections.emptyList(); } } catch (IOException e) { throw new HoodieIOException("Failed to load instant states, path: " + instantStatePath, e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy