<pre name="code" class="java">;; 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.
;;
;;主要负责调用java端的进程间通信的接口,包了一层,这样就可以通过它实现在clojure主逻辑做进程间通信。(后期版本是netty实现)
;;
;;mk-context 调用 LocalContext,LocalContext调用 LocalConnection ,LocalConnection 调用add-queue
;;对外暴露一个 mk-context函数,返回LocalContext。 就可以使用进程间通信。
(ns backtype.storm.messaging.local
(:refer-clojure :exclude [send])
(:use [backtype.storm log])
(:import [backtype.storm.messaging IContext IConnection TaskMessage])
(:import [java.util.concurrent LinkedBlockingQueue])
(:import [java.util Map Iterator])
(:import [java.util Iterator ArrayList])
(:gen-class))
;;这是有个方法。添加队列的。辅助方法
(defn add-queue! [queues-map lock storm-id port]
(let [id (str storm-id "-" port)]
(locking lock
(when-not (contains? @queues-map id)
(swap! queues-map assoc id (LinkedBlockingQueue.))))
(@queues-map id)))
;;这个是java那边netty映射到clojure端的conection
(deftype LocalConnection [storm-id port queues-map lock queue]
IConnection
(^Iterator recv [this ^int flags ^int clientId]
(when-not queue
(throw (IllegalArgumentException. "Cannot receive on this socket")))
(let [ret (ArrayList.)
msg (if (= flags 1) (.poll queue) (.take queue))]
(if msg
(do
(.add ret msg)
(.iterator ret))
nil)))
(^void send [this ^int taskId ^bytes payload]
(let [send-queue (add-queue! queues-map lock storm-id port)]
(.put send-queue (TaskMessage. taskId payload))
))
(^void send [this ^Iterator iter]
(let [send-queue (add-queue! queues-map lock storm-id port)]
(while (.hasNext iter)
(.put send-queue (.next iter)))
))
(^void close [this]
))
;;这个是java那边netty映射到clojure端的Context,里面持有LocalConnection
(deftype LocalContext [^{:unsynchronized-mutable true} queues-map
^{:unsynchronized-mutable true} lock]
IContext
(^void prepare [this ^Map storm-conf]
(set! queues-map (atom {}))
(set! lock (Object.)))
(^IConnection bind [this ^String storm-id ^int port]
(LocalConnection. storm-id port queues-map lock (add-queue! queues-map lock storm-id port)))
(^IConnection connect [this ^String storm-id ^String host ^int port]
(LocalConnection. storm-id port queues-map lock nil))
(^void term [this]
))
;;这个返回LocalContext,给主流程做消息传递逻辑
(defn mk-context []
(let [context (LocalContext. nil nil)]
(.prepare ^IContext context nil)
context))
03 storm 源码阅读 storm的进程间消息通信实现clojure端 加载java端netty能力
最新推荐文章于 2020-12-06 13:34:42 发布