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

webapp.src.components.WorkerThreadList.jsx Maven / Gradle / Ivy

There is a newer version: 468
Show newest version
/*
 * Licensed 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.
 */

import React from "react";

import {
    getFirstParameter
} from "../utils";

const ALL_THREADS = "All Threads";
const QUERY_THREADS = "Running Queries";

const ALL_THREAD_STATE = "ALL";
const THREAD_STATES = [ALL_THREAD_STATE, "RUNNABLE", "BLOCKED", "WAITING", "TIMED_WAITING", "NEW", "TERMINATED"];
const QUERY_THREAD_REGEX = new RegExp(/([0-9])*_([0-9])*_([0-9])*_.*?\.([0-9])*\.([0-9])*-([0-9])*-([0-9])*/);
const THREAD_GROUP_REGEXP = new RegExp(/(.*?)-[0-9]+/);

export class WorkerThreadList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            serverInfo: null,
            initialized: false,
            ended: false,

            threads: null,

            snapshotTime: null,

            selectedGroup: ALL_THREADS,
            selectedThreadState: ALL_THREAD_STATE,
        };
    }

    captureSnapshot() {
        const nodeId = getFirstParameter(window.location.search);
        $.get('/ui/api/worker/' + nodeId + '/thread', function (threads) {
            this.setState({
                threads: WorkerThreadList.processThreads(threads),
                snapshotTime: new Date(),
                initialized: true,
            });
        }.bind(this))
        .fail(function () {
            this.setState({
                initialized: true,
            });
        }.bind(this));
    }

    componentDidUpdate() {
        new window.ClipboardJS('.copy-button');
    }

    static processThreads(threads) {
        const result = {};

        result[ALL_THREADS] = threads;

        for (let i = 0; i < threads.length; i++) {
            const thread = threads[i];
            if (thread.name.match(QUERY_THREAD_REGEX)) {
                if (!result[QUERY_THREADS]) {
                    result[QUERY_THREADS] = [];
                }
                result[QUERY_THREADS].push(thread)
            }

            const match = THREAD_GROUP_REGEXP.exec(thread.name);
            const threadGroup = match ? match[1] : thread.name;
            if (!result[threadGroup]) {
                result[threadGroup] = [];
            }
            result[threadGroup].push(thread);
        }

        return result
    }

    handleGroupClick(selectedGroup, event) {
        this.setState({
            selectedGroup: selectedGroup
        });
        event.preventDefault();
    }

    handleThreadStateClick(selectedThreadState, event) {
        this.setState({
            selectedThreadState: selectedThreadState
        });
        event.preventDefault();
    }

    handleNewSnapshotClick(event) {
        this.setState({
            initialized: false
        });
        this.captureSnapshot();
        event.preventDefault();
    }

    filterThreads(group, state) {
        return this.state.threads[group].filter(t => t.state === state || state === ALL_THREAD_STATE);
    }

    renderGroupListItem(group) {
        return (
            
  • {group} ({this.filterThreads(group, this.state.selectedThreadState).length})
  • ); } renderThreadStateListItem(threadState) { return (
  • {threadState} ({this.filterThreads(this.state.selectedGroup, threadState).length})
  • ); } renderStackLine(threadId) { return (stackLine, index) => { return (
      at {stackLine.className}.{stackLine.method} ({stackLine.file}:{stackLine.line})
    ); }; } renderThread(threadInfo) { return (
    {threadInfo.name} {threadInfo.state} #{threadInfo.id} {threadInfo.lockOwnerId}
    {threadInfo.stackTrace.map(this.renderStackLine(threadInfo.id))}
     
    ); } render() { const threads = this.state.threads; let display = null; let toolbar = null; if (threads === null) { if (this.state.initialized === false) { display = (
    ); } else { display = (

    Thread snapshot could not be loaded

    ); } } else { toolbar = (
    Snapshot at {this.state.snapshotTime.toTimeString()}         
      {Object.keys(threads).map(group => this.renderGroupListItem(group))}
      {THREAD_STATES.map(state => this.renderThreadStateListItem(state))}
    ); const filteredThreads = this.filterThreads(this.state.selectedGroup, this.state.selectedThreadState); let displayedThreads; if (filteredThreads.length === 0 && this.state.selectedThreadState === ALL_THREAD_STATE) { displayedThreads = (

    No threads in group '{this.state.selectedGroup}'

    ); } else if (filteredThreads.length === 0 && this.state.selectedGroup === ALL_THREADS) { displayedThreads = (

    No threads with state {this.state.selectedThreadState}

    ); } else if (filteredThreads.length === 0) { displayedThreads = (

    No threads in group '{this.state.selectedGroup}' with state {this.state.selectedThreadState}

    ); } else { displayedThreads = (
                            {filteredThreads.map(t => this.renderThread(t))}
                        
    ); } display = (
    {displayedThreads}
    ); } return (

    Thread Snapshot  

    {toolbar}

    {display}
    ); } }




    © 2015 - 2025 Weber Informatics LLC | Privacy Policy