privatestaticfinal Object[] OBJECTS0 = new Object[0];
privatelong createTime; private Node curNode; /** * {@link Node} of the specific origin, Usually the origin is the Service Consumer. */ private Node originNode; private Throwable error; protected ResourceWrapper resourceWrapper;
public ResourceWrapper getResourceWrapper(){ return resourceWrapper; } // 退出时执行 /** * Complete the current resource entry and restore the entry stack in context. * * @throws ErrorEntryFreeException if entry in current context does not match current entry */ publicvoidexit()throws ErrorEntryFreeException { exit(1, OBJECTS0); }
/** * Equivalent to {@link #exit()}. Support try-with-resources since JDK 1.7. * * @since 1.5.0 */ @Override publicvoidclose(){ exit(); }
/** * Exit this entry. This method should invoke if and only if once at the end of the resource protection. * * @param count tokens to release. * @param args extra parameters * @throws ErrorEntryFreeException, if {@link Context#getCurEntry()} is not this entry. */ publicabstractvoidexit(int count, Object... args)throws ErrorEntryFreeException;
/** * Exit this entry. * * @param count tokens to release. * @param args extra parameters * @return next available entry after exit, that is the parent entry. * @throws ErrorEntryFreeException, if {@link Context#getCurEntry()} is not this entry. */ protectedabstract Entry trueExit(int count, Object... args)throws ErrorEntryFreeException;
/** * Get related {@link Node} of the parent {@link Entry}. * * @return */ publicabstract Node getLastNode();
/** * Get origin {@link Node} of the this {@link Entry}. * * @return origin {@link Node} of the this {@link Entry}, may be null if no origin specified by * {@link ContextUtil#enter(String name, String origin)}. */ public Node getOriginNode(){ return originNode; }
private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args) throws BlockException { // 从ThreadLocal中获取上下文 Context context = ContextUtil.getContext(); if (context instanceof NullContext) { // The {@link NullContext} indicates that the amount of context has exceeded the threshold, // so here init the entry only. No rule checking will be done. returnnew CtEntry(resourceWrapper, null, context); } // 使用默认上下文 if (context == null) { // Using default context. context = MyContextUtil.myEnter(Constants.CONTEXT_DEFAULT_NAME, "", resourceWrapper.getType()); }
// Global switch is close, no rule checking will do. if (!Constants.ON) { returnnew CtEntry(resourceWrapper, null, context); } // 生成插槽链 ProcessorSlot<Object> chain = lookProcessChain(resourceWrapper);
/* * Means amount of resources (slot chain) exceeds {@link Constants.MAX_SLOT_CHAIN_SIZE}, * so no rule checking will be done. */ if (chain == null) { returnnew CtEntry(resourceWrapper, null, context); } // 生成带插槽链的 Entry Entry e = new CtEntry(resourceWrapper, chain, context); try { // 这里执行 chain.entry chain.entry(context, resourceWrapper, null, count, prioritized, args); } catch (BlockException e1) { e.exit(count, args); throw e1; } catch (Throwable e1) { // This should not happen, unless there are errors existing in Sentinel internal. RecordLog.info("Sentinel unexpected exception", e1); } return e; }