### Elasticsearch Version

7.17, 8.0

### Installed Plugins

_No response_

### Java Version

_bundled_

### OS Version

n/a

### Problem Description

The TransportDeprecationInfoAction calls DeprecationInfoAction on the current thread, which is a transport_worker thread. Unfortunately if there are a lot of indices this can take tens of seconds. And since it is on the transport_worker thread it can interfere with communication to and from the other machines in the cluster. The result is that this machine (the master) will see that other nodes are not responding, and remove them from the cluster. And other nodes will see that the master is not responding, so they will elect a new master.

### Steps to Reproduce

We have seen this on a cluster with ~5500 indices and ~22,000 fields total. Just running 
```
GET _migration/deprecations
```
will do it.

### Logs (if relevant)

Here is an example thread from our hot_threads log:
```
   100.1% [cpu=100.1%, other=0.0%] (500.4ms out of 500ms) cpu usage by thread 'elasticsearch[es-prod-es-rack1-controller-0][transport_worker][T#7]'
     2/10 snapshots sharing following 120 elements
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readValueUnsafe(AbstractXContentParser.java:394)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readMapEntries(AbstractXContentParser.java:318)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readValueUnsafe(AbstractXContentParser.java:394)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readMapEntries(AbstractXContentParser.java:318)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readValueUnsafe(AbstractXContentParser.java:394)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readMapEntries(AbstractXContentParser.java:318)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readValueUnsafe(AbstractXContentParser.java:394)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readMapEntries(AbstractXContentParser.java:318)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.readMapSafe(AbstractXContentParser.java:304)
       app//org.elasticsearch.xcontent.support.AbstractXContentParser.mapOrdered(AbstractXContentParser.java:259)
       app//org.elasticsearch.common.xcontent.XContentHelper.convertToMap(XContentHelper.java:188)
       app//org.elasticsearch.common.xcontent.XContentHelper.convertToMap(XContentHelper.java:147)
       app//org.elasticsearch.common.xcontent.XContentHelper.convertToMap(XContentHelper.java:106)
       app//org.elasticsearch.cluster.metadata.MappingMetadata.sourceAsMap(MappingMetadata.java:142)
       app//org.elasticsearch.cluster.metadata.MappingMetadata.getSourceAsMap(MappingMetadata.java:154)
       org.elasticsearch.xpack.deprecation.IndexDeprecationChecks.checkGeoShapeMappings(IndexDeprecationChecks.java:729)
       org.elasticsearch.xpack.deprecation.DeprecationChecks.lambda$static$34(DeprecationChecks.java:268)
       org.elasticsearch.xpack.deprecation.DeprecationChecks$$Lambda$1089/0x000000080100d000.apply(Unknown Source)
       org.elasticsearch.xpack.deprecation.DeprecationInfoAction$Response.lambda$from$3(DeprecationInfoAction.java:285)
       org.elasticsearch.xpack.deprecation.DeprecationInfoAction$Response$$Lambda$8943/0x00000008020b1d90.apply(Unknown Source)
       java.base@17.0.2/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
       java.base@17.0.2/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
       java.base@17.0.2/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
       java.base@17.0.2/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
       java.base@17.0.2/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
       java.base@17.0.2/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
       java.base@17.0.2/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
       org.elasticsearch.xpack.deprecation.DeprecationInfoAction.filterChecks(DeprecationInfoAction.java:68)
       org.elasticsearch.xpack.deprecation.DeprecationInfoAction$Response.from(DeprecationInfoAction.java:285)
       org.elasticsearch.xpack.deprecation.TransportDeprecationInfoAction.lambda$masterOperation$1(TransportDeprecationInfoAction.java:130)
       org.elasticsearch.xpack.deprecation.TransportDeprecationInfoAction$$Lambda$8747/0x0000000801ef1468.accept(Unknown Source)
       app//org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:136)
       org.elasticsearch.xpack.deprecation.TransportDeprecationInfoAction.lambda$pluginSettingIssues$4(TransportDeprecationInfoAction.java:160)
       org.elasticsearch.xpack.deprecation.TransportDeprecationInfoAction$$Lambda$8750/0x0000000801ef1b20.accept(Unknown Source)
       app//org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:136)
       app//org.elasticsearch.action.support.GroupedActionListener.onResponse(GroupedActionListener.java:55)
       org.elasticsearch.xpack.deprecation.MlDeprecationChecker.lambda$check$1(MlDeprecationChecker.java:133)
       org.elasticsearch.xpack.deprecation.MlDeprecationChecker$$Lambda$8786/0x0000000801ef3c00.accept(Unknown Source)
       app//org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:136)
       app//org.elasticsearch.action.support.ContextPreservingActionListener.onResponse(ContextPreservingActionListener.java:31)
       app//org.elasticsearch.action.support.TransportAction$1.onResponse(TransportAction.java:88)
       app//org.elasticsearch.action.support.TransportAction$1.onResponse(TransportAction.java:82)
       app//org.elasticsearch.action.support.ContextPreservingActionListener.onResponse(ContextPreservingActionListener.java:31)
       org.elasticsearch.xpack.security.action.filter.SecurityActionFilter.lambda$applyInternal$2(SecurityActionFilter.java:192)
       org.elasticsearch.xpack.security.action.filter.SecurityActionFilter$$Lambda$6585/0x0000000801e1c8d0.accept(Unknown Source)
       app//org.elasticsearch.action.ActionListener$DelegatingFailureActionListener.onResponse(ActionListener.java:219)
       org.elasticsearch.xpack.ml.action.TransportGetModelSnapshotsAction.lambda$getModelSnapshots$2(TransportGetModelSnapshotsAction.java:81)
       org.elasticsearch.xpack.ml.action.TransportGetModelSnapshotsAction$$Lambda$8791/0x000000080204af50.accept(Unknown Source)
       org.elasticsearch.xpack.ml.job.persistence.JobResultsProvider.lambda$modelSnapshots$31(JobResultsProvider.java:1309)
       org.elasticsearch.xpack.ml.job.persistence.JobResultsProvider$$Lambda$8799/0x000000080204ba50.accept(Unknown Source)
       app//org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:136)
       app//org.elasticsearch.action.support.ContextPreservingActionListener.onResponse(ContextPreservingActionListener.java:31)
       app//org.elasticsearch.action.support.TransportAction$1.onResponse(TransportAction.java:88)
       app//org.elasticsearch.action.support.TransportAction$1.onResponse(TransportAction.java:82)
       app//org.elasticsearch.action.support.ContextPreservingActionListener.onResponse(ContextPreservingActionListener.java:31)
       org.elasticsearch.xpack.security.action.filter.SecurityActionFilter.lambda$applyInternal$2(SecurityActionFilter.java:192)
       org.elasticsearch.xpack.security.action.filter.SecurityActionFilter$$Lambda$6585/0x0000000801e1c8d0.accept(Unknown Source)
       app//org.elasticsearch.action.ActionListener$DelegatingFailureActionListener.onResponse(ActionListener.java:219)
       app//org.elasticsearch.action.ActionListener$RunAfterActionListener.onResponse(ActionListener.java:341)
       app//org.elasticsearch.action.search.AbstractSearchAsyncAction.sendSearchResponse(AbstractSearchAsyncAction.java:707)
       app//org.elasticsearch.action.search.ExpandSearchPhase.run(ExpandSearchPhase.java:106)
       app//org.elasticsearch.action.search.AbstractSearchAsyncAction.executePhase(AbstractSearchAsyncAction.java:454)
       app//org.elasticsearch.action.search.AbstractSearchAsyncAction.executeNextPhase(AbstractSearchAsyncAction.java:448)
       app//org.elasticsearch.action.search.FetchSearchPhase.moveToNextPhase(FetchSearchPhase.java:287)
       app//org.elasticsearch.action.search.FetchSearchPhase.lambda$innerRun$1(FetchSearchPhase.java:114)
       app//org.elasticsearch.action.search.FetchSearchPhase$$Lambda$6996/0x0000000801eadd30.run(Unknown Source)
       app//org.elasticsearch.action.search.CountedCollector.countDown(CountedCollector.java:40)
       app//org.elasticsearch.action.search.CountedCollector$$Lambda$8804/0x0000000802099440.run(Unknown Source)
       app//org.elasticsearch.action.search.ArraySearchPhaseResults.consumeResult(ArraySearchPhaseResults.java:35)
       app//org.elasticsearch.action.search.CountedCollector.onResult(CountedCollector.java:48)
       app//org.elasticsearch.action.search.FetchSearchPhase$2.innerOnResponse(FetchSearchPhase.java:226)
       app//org.elasticsearch.action.search.FetchSearchPhase$2.innerOnResponse(FetchSearchPhase.java:220)
       app//org.elasticsearch.action.search.SearchActionListener.onResponse(SearchActionListener.java:33)
       app//org.elasticsearch.action.search.SearchActionListener.onResponse(SearchActionListener.java:18)
       app//org.elasticsearch.action.ActionListenerResponseHandler.handleResponse(ActionListenerResponseHandler.java:43)
       app//org.elasticsearch.action.search.SearchTransportService$ConnectionCountingHandler.handleResponse(SearchTransportService.java:642)
       app//org.elasticsearch.transport.TransportService$4.handleResponse(TransportService.java:847)
       app//org.elasticsearch.transport.TransportService$ContextRestoreResponseHandler.handleResponse(TransportService.java:1471)
       app//org.elasticsearch.transport.InboundHandler.doHandleResponse(InboundHandler.java:340)
       app//org.elasticsearch.transport.InboundHandler.handleResponse(InboundHandler.java:324)
       app//org.elasticsearch.transport.InboundHandler.messageReceived(InboundHandler.java:134)
       app//org.elasticsearch.transport.InboundHandler.inboundMessage(InboundHandler.java:88)
       app//org.elasticsearch.transport.TcpTransport.inboundMessage(TcpTransport.java:743)
       org.elasticsearch.transport.netty4.Netty4MessageChannelHandler$$Lambda$6021/0x0000000801b7e510.accept(Unknown Source)
       app//org.elasticsearch.transport.InboundPipeline.forwardFragments(InboundPipeline.java:147)
       app//org.elasticsearch.transport.InboundPipeline.doHandleBytes(InboundPipeline.java:119)
       app//org.elasticsearch.transport.InboundPipeline.handleBytes(InboundPipeline.java:84)
       org.elasticsearch.transport.netty4.Netty4MessageChannelHandler.channelRead(Netty4MessageChannelHandler.java:71)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
       io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
       io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:280)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
       io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
       io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
       io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
       io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1374)
       io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1237)
       io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1286)
       io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:507)
       io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:446)
       io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
       io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
       io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
       io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
       io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
       io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
       io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
       io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:620)
       io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:583)
       io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
       io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
       io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
       java.base@17.0.2/java.lang.Thread.run(Thread.java:833)
```
x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationInfoAction.java
return checks.stream().map(mapper).filter(Objects::nonNull).collect(Collectors.toList());
    }
    /**
     * This method rolls up DeprecationIssues that are identical but on different nodes. It also roles up DeprecationIssues that are
     * identical (and on different nodes) except that they differ in the removable settings listed in their meta object. We roll these up
     * by taking the intersection of all removable settings in otherwise identical DeprecationIssues. That way we don't claim that a
     * setting can be automatically removed if any node has it in its elasticsearch.yml.
     * @param response
     * @return
     */
    private static List<DeprecationIssue> mergeNodeIssues(NodesDeprecationCheckResponse response) {
        
        Collection<List<Tuple<DeprecationIssue, String>>> issuesToMerge = getDeprecationIssuesThatDifferOnlyByMeta(response.getNodes());
        
        Map<DeprecationIssue, List<String>> issueToListOfNodesMap = getMergedIssuesToNodesMap(issuesToMerge);
        return issueToListOfNodesMap.entrySet().stream().map(entry -> {
            DeprecationIssue issue = entry.getKey();
            String details = issue.getDetails() != null ? issue.getDetails() + " " : "";
            return new DeprecationIssue(
                issue.getLevel(),
                issue.getMessage(),
                issue.getUrl(),
                details + "(nodes impacted: " + entry.getValue() + ")",
                issue.isResolveDuringRollingUpgrade(),
                issue.getMeta()
            );
        }).collect(Collectors.toList());
    }
    /*
     * This method pulls all of the DeprecationIssues from the given nodeResponses, and buckets them into lists of DeprecationIssues that