text:
75" x2="20.3454" y2="38.862" width="0.254" layer="1"/>
<wire x1="7.4295" y1="37.1475" x2="18.6309" y2="37.1475" width="0.254" layer="1"/>
<wire x1="6.858" y1="36.576" x2="7.4295" y2="37.1475" width="0.254" layer="16"/>
<wire x1="5.715" y1="36.576" x2="6.858" y2="36.576" width="0.254" layer="16"/>
<wire x1="3.8862" y1="34.7472" x2="5.715" y2="36.576" width="0.254" layer="16"/>
<wire x1="3.8862" y1="34.4043" x2="3.8862" y2="34.7472" width="0.254" layer="16"/>
<wire x1="3.8862" y1="34.4043" x2="3.81" y2="34.29" width="0.254" layer="16"/>
<via x="4.4577" y="17.145" extent="1-16" drill="0.3302"/>
<via x="4.9149" y="24.8031" extent="1-16" drill="0.3302"/>
<via x="4.4577" y="31.0896" extent="1-16" drill="0.3302"/>
<via x="7.4295" y="37.1475" extent="1-16" drill="0.3302"/>
</signal>
<signal name="BUFFER_G1">
<contactref element="IC1" pad="6"/>
<contactref element="IC2" pad="8"/>
<contactref element="J2" pad="21A"/>
<contactref element="J2" pad="21B"/>
<wire x1="13.9446" y1="67.3227" x2="13.9446" y2="69.8373" width="0.254" layer="1"/>
<wire x1="13.9446" y1="69.8373" x2="13.97" y2="69.85" width="0.254" layer="1"/>
<wire x1="13.9446" y1="67.3227" x2="13.97" y2="67.31" width="0.254" layer="1"/>
<wire x1="6.2865" y1="24.4602" x2="6.2865" y2="21.6027" width="0.254" layer="16"/>
<wire x1="5.2578" y1="25.4889" x2="6.2865" y2="24.4602" width="0.254" layer="16"/>
<wire x1="5.2578" y1="35.433" x2="5.2578" y2="25.4889" width="0.254" layer="16"/>
<wire x1="5.9436" y1="36.1188" x2="5.2578" y2="35.433" width="0.254" layer="16"/>
<wire x1="9.6012" y1="36.1188" x2="5.9436" y2="36.1188" width="0.254" layer="16"/>
<wire x1="11.43" y1="34.29" x2="9.6012" y2="36.1188" width="0.254" layer="16"/>
<wire x1="6.2865" y1="21.6027" x2="6.35" y2="21.59" width="0.254" layer="16"/>
<wire x1="13.9446" y1="60.1218" x2="13.9446" y2="67.2084" width="0.254" layer="16"/>
<wire x1="11.7729" y1="57.9501" x2="13.9446" y2="60.1218" width="0.254" layer="16"/>
<wire x1="11.7729" y1="45.6057" x2="11.7729" y2="57.9501" width="0.254" layer="16"/>
<wire x1="10.1727" y1="44.0055" x2="11.7729" y2="45.6057" width="0.254" layer="16"/>
<wire x1="10.1727" y1="36.8046" x2="10.1727" y2="44.0055" width="0.254" layer="16"/>
<wire x1="9.6012" y1="36.2331" x2="10.1727" y2="36.8046" width="0.254" layer="16"/>
<wire x1="13.9446" y1="67.2084" x2="13.97" y2="67.31" width="0.254" layer="16"/>
<wire x1="9.6012" y1="36.2331" x2="9.6012" y2="36.1188" width="0.254" layer="16"/>
</signal>
<signal name="BUFFER_B1">
<contactref element="IC1" pad="7"/>
<contactref element="IC2" pad="13"/>
<contactref element="J2" pad="22A"/>
<contactref element="J2" pad="22B"/>
<wire x1="6.4008" y1="67.3227" x2="6.4008" y2="69.8373" width="0.254" layer="1"/>
<wire x1="6.4008" y1="69.8373" x2="6.35" y2="69.85" width="0.254" layer="1"/>
<wire x1="6.4008" y1="67.3227" x2="6.35" y2="67.31" width="0.254" layer="1"/>
<wire x1="6.6294" y1="13.9446" x2="6.4008" y2="13.9446" width="0.254" layer="16"/>
<wire x1="8.4582" y1="12.1158" x2="6.6294" y2="13.9446" width="0.254" layer="16"/>
<wire x1="9.2583" y1="12.1158" x2="8.4582" y2="12.1158" width="0.254" layer="16"/>
<wire x1="9.9441" y1="12.8016" x2="9.2583" y2="12.1158" width="0.254" layer="16"/>
<wire x1="9.9441" y1="33.2613" x2="9.9441" y2="12.8016" width="0.254" layer="16"/>
<wire x1="8.9154" y1="34.29" x2="9.9441" y2="33.2613" width="0.254" layer="16"/>
<wire x1="6.4008" y1="13.9446" x2="6.35" y2="13.97" width="0.254" layer="16"/>
<wire x1="8.9154" y1="34.29" x2="8.89" y2="34.29" width="0.254" layer="16"/>
<wire x1="5.4864" y1="69.9516" x2="6.2865" y2="69.9516" width="0.254" layer="1"/>
<wire x1="4.3434" y1="71.0946" x2="5.4864" y2="69.9516" width="0.254" layer="1"/>
<wire x1="3.3147" y1="71.0946" x2="4.3434" y2="71.0946" width="0.254" layer="1"/>
<wire x1="2.5146" y1="70.2945" x2="3.3147" y2="71.0946" width="0.254" layer="1"/>
<wire x1="2.5146" y1="64.008" x2="2.5146" y2="70.2945" width="0.254" layer="1"/>
<wire x1="0.8001" y1="62.2935" x2="2.5146" y2="64.008" width="0.254" layer="1"/>
<wire x1="0.8001" y1="54.0639" x2="0.8001" y2="62.2935" width="0.254" layer="1"/>
<wire x1="4.4577" y1="50.4063" x2="0.8001" y2="54.0639" width="0.254" layer="1"/>
<wire x1="4.4577" y1="42.9768" x2="4.4577" y2="50.4063" width="0.254" layer="1"/>
<wire x1="5.1435" y1="42.291" x2="4.4577" y2="42.9768" width="0.254" layer="1"/>
<wire x1="5.1435" y1="33.2613" x2="5.1435" y2="42.291" width="0.254" layer="1"/>
<wire x1="5.9436" y1="32.4612" x2="5.1435" y2="33.2613" width="0.254" layer="1"/>
<wire x1="6.9723" y1="32.4612" x2="5.9436" y2="32.4612" width="0.254" layer="1"/>
<wire x1="8.8011" y1="34.29" x2="6.9723" y2="32.4612" width="0.254" layer="1"/>
<wire x1="6.2865" y1="69.9516" x2="6.35" y2="69.85" width="0.254" layer="1"/>
<wire x1="8.8011" y1="34.29" x2="8.89" y2="34.29" width="0.254" layer="1"/>
</signal>
<signal name="BUFFER_G2">
<contactref element="IC1" pad="8"/>
<contactref element="IC2" pad="14"/>
<contactref element="J1" pad="25A"/>
<contactref element="J1" pad="25B"/>
<wire x1="21.6027" y1="39.4335" x2="21.6027" y2="41.8338" width="0.254" layer="1"/>
<wire x1="21.6027" y1="41.8338" x2="21.59" y2="41.91" width="0.254" layer="1"/>
<wire x1="21.6027" y1="39.4335" x2="21.59" y2="39.37" width="0.254" layer="1"/>
<wire x1="8.8011" y1="19.431" x2="8.8011" y2="14.0589" width="0.254" layer="16"/>
<wire x1="7.4295" y1="20.8026" x2="8.8011" y2="19.431" width="0.254" layer="16"/>
<wire x1="7.4295" y1="33.2613" x2="7.4295" y2="20.8026" width="0.254" layer="16"/>
<wire x1="6.4008" y1="34.29" x2="7.4295" y2="33.2613" width="0.254" layer="16"/>
<wire x1="8.8011" y1="14.0589" x2="8.89" y2="13.97" width="0.254" layer="16"/>
<wire x1="6.4008" y1="34.29" x2="6.35" y2="34.29" width="0.254" layer="16"/>
<wire x1="18.288" y1="36.1188" x2="21.4884" y2="39.3192" width="0.254" layer="1"/>
<wire x1="8.2296" y1="36.1188" x2="18.288" y2="36.1188" width="0.254" layer="1"/>
<wire x1="6.4008" y1="34.29" x2="8.2296" y2="36.1188" width="0.254" layer="1"/>
<wire x1="21.4884" y1="39.3192" x2="21.59" y2="39.37" width="0.254" layer="1"/>
<wire x1="6.4008" y1="34.29" x2="6.35" y2="34.29" width="0.254" layer="1"/>
</signal>
<signal name="BUFFER_R2">
<contactref element="IC1" pad="3"/>
<contactref element="IC2" pad="3"/>
<contactref element="J2" pad="2B"/>
<contactref element="J2" pad="2A"/>
<wire x1="36.8046" y1="67.3227" x2="36.8046" y2="69.8373" width="0.254" layer="1"/>
<wire x1="36.8046" y1="69.8373" x2="36.83" y2="69.85" width="0.254" layer="1"/>
<wire x1="36.8046" y1="67.3227" x2="36.83" y2="67.31" width="0.254" layer="1"/>
<wire x1="19.0881" y1="24.4602" x2="19.0881" y2="21.6027" width="0.254" layer="16"/>
<wire x1="20.1168" y1="25.4889" x2="19.0881" y2="24.4602" width="0.254" layer="16"/>
<wire x1="20.1168" y1="33.2613" x2="20.1168" y2="25.4889" width="0.254" layer="16"/>
<wire x1="19.0881" y1="34.29" x2="20.1168" y2="33.2613" width="0.254" layer="16"/>
<wire x1="19.0881" y1="21.6027" x2="19.05" y2="21.59" width="0.254" layer="16"/>
<wire x1="19.0881" y1="34.29" x2="19.05" y2="34.29" width="0.254" layer="16"/>
<wire x1="36.8046" y1="61.2648" x2="36.8046" y2="67.2084" width="0.254" layer="16"/>
<wire x1="29.3751" y1="53.8353" x2="36.8046" y2="61.2648" width="0.254" layer="16"/>
<wire x1="27.7749" y1="53.8353" x2="29.3751" y2="53.8353" width="0.254" layer="16"/>
<wire x1="24.2316" y1="50.292" x2="27.7749" y2="53.8353" width="0.254" layer="16"/>
<wire x1="24.2316" y1="47.8917" x2="24.2316" y2="50.292" width="0.254" layer="16"/>
<wire x1="20.3454" y1="44.0055" x2="24.2316" y2="47.8917" width="0.254" layer="16"/>
<wire x1="20.3454" y1="35.6616" x2="20.3454" y2="44.0055" width="0.254" layer="16"/>
<wire x1="19.0881" y1="34.4043" x2="20.3454" y2="35.6616" width="0.254" layer="16"/>
<wire x1="36.8046" y1="67.2084" x2="36.83" y2="67.31" width="0.254" layer="16"/>
<wire x1="19.0881" y1="34.4043" x2="19.05" y2="34.29" width="0.254" layer="16"/>
</signal>
<signal name="BUFFER_B2">
<contactref element="IC1" pad="4"/>
<contactref element="IC2" pad="4"/>
<contactref element="J2" pad="0B"/>
<contactref element="J2" pad="0A"/>
<wire x1="34.29" y1="67.31" x2="34.29" y2="69.85" width="0.254" layer="1"/>
<wire x1="16.4592" y1="24.4602" x2="16.4592" y2="21.6027" width="0.254" layer="16"/>
<wire x1="15.4305" y1="25.4889" x2="16.4592" y2="24.4602" width="0.254" layer="16"/>
<wire x1="15.4305" y1="32.8041" x2="15.4305" y2="25.4889" width="0.254" layer="16"/>
<wire x1="16.4592" y1="33.8328" x2="15.4305" y2="32.8041" width="0.254" layer="16"/>
<wire x1="16.4592" y1="34.29" x2="16.4592" y2="33.8328" width="0.254" layer="16"/>
<wire x1="16.4592" y1="21.6027" x2="16.51" y2="21.59" width="0.254" layer="16"/>
<wire x1="16.4592" y1="34.29" x2="16.51" y2="34.29" width="0.254" layer="16"/>
<wire x1="34.29" y1="66.5226" x2="34.29" y2="67.31" width="0.254" layer="16"/>
<wire x1="28.2321" y1="60.4647" x2="34.29" y2="66.5226" width="0.254" layer="16"/>
<wire x1="26.4033" y1="60.4647" x2="28.2321" y2="60.4647" width="0.254" layer="16"/>
<wire x1="23.4315" y1="57.4929" x2="26.4033" y2="60.4647" width="0.254" layer="16"/>
<wire x1="22.7457" y1="57.4929" x2="23.4315" y2="57.4929" width="0.254" layer="16"/>
<wire x1="21.9456" y1="56.6928" x2="22.7457" y2="57.4929" width="0.254" layer="16"/>
<wire x1="21.9456" y1="53.4924" x2="21.9456" y2="56.6928" width="0.254" layer="16"/>
<wire x1="19.431" y1="50.9778" x2="21.9456" y2="53.4924" width="0.254" layer="16"/>
<wire x1="19.431" y1="45.6057" x2="19.431" y2="50.9778" width="0.254" layer="16"/>
<wire x1="17.7165" y1="43.8912" x2="19.431" y2="45.6057" width="0.254" layer="16"/>
<wire x1="17.7165" y1="35.5473" x2="17.7165" y2="43.8912" width="0.254" layer="16"/>
<wire x1="16.5735" y1="34.4043" x2="17.7165" y2="35.5473" width="0.254" layer="16"/>
<wire x1="16.5735" y1="34.4043" x2="16.51" y2="34.29" width="0.254" layer="16"/>
</signal>
<signal name="PANEL_ADX4">
<contactref element="J4" pad="8"/>
<contactref element="IC2" pad="15"/>
<wire x1="11.7729" y1="13.9446" x2="11.43" y2="13.9446" width="0.254" layer="1"/>
<wire x1="14.9733" y1="10.7442" x2="11.7729" y2="13.9446" width="0.254" layer="1"/>
<wire x1="20.3454" y1="10.7442" x2="14.9733" y2="10.7442" width="0.254" layer="1"/>
<wire x1="21.4884" y1="9.6012" x2="20.3454" y2="10.7442" width="0.254" layer="1"/>
<wire x1="21.4884" y1="6.4008" x2="21.4884" y2="9.6012" width="0.254" layer="1"/>
<wire x1="11.43" y1="13.9446" x2="11.43" y2="13.97" width="0.254" layer="1"/>
<wire x1="21.4884" y1="6.4008" x2="21.59" y2="6.35" width="0.254" layer="1"/>
</signal>
<signal name="CLK1">
<contactref element="J3" pad="3"/>
<contactref element="IC5" pad="6"/>
<wire x1="31.7754" y1="33.9471" x2="31.7754" y2="34.29" width="0.254" layer="1"/>
<wire x1="38.2905" y1="27.432" x2="31.7754" y2="33.9471" width="0.254" layer="1"/>
<wire x1="38.2905" y1="21.6027" x2="38.2905" y2="27.432" width="0.254" layer="1"/>
<wire x1="43.8912" y1="16.002" x2="38.2905" y2="21.6027" width="0.254" layer="1"/>
<wire x1="31.7754" y1="34.29" x2="31.75" y2="34.29" width="0.254" layer="1"/>
<wire x1="43.8912" y1="16.002" x2="43.942" y2="16.002" width="0.254" layer="1"/>
</signal>
<signal name="DAT1">
<contactref element="J3" pad="2"/>
<contactref element="IC5" pad="3"/>
<wire x1="39.4335" y1="28.8036" x2="39.4335" y2="34.29" width="0.254" layer="1"/>
<wire x1="40.8051" y1="27.432" x2="39.4335" y2="28.8036" width="0.254" layer="1"/>
<wire x1="40.8051" y1="21.717" x2="40.8051" y2="27.432" width="0.254" layer="1"/>
<wire x1="43.8912" y1="18.6309" x2="40.8051" y2="21.717" width="0.254" layer="1"/>
<wire x1="39.4335" y1="34.29" x2="39.37" y2="34.29" width="0.254" layer="1"/>
<wire x1="43.8912" y1="18.6309" x2="43.942" y2="18.542" width="0.254" layer="1"/>
</signal>
<signal name="N$4">
<contactref element="R2" pad="1"/>
<contactref element="R1" pad="2"/>
<contactref element="JP1" pad="2"/>
<contactref element="IC5" pad="2"/>
<contactref element="IC5" pad="5"/>
<contactref element="R2-THT" pad="1"/>
<contactref element="R1-THT" pad="2"/>
<wire x1="41.91" y1="64.77" x2="41.91" y2="63.5" width="0.254" layer="1"/>
<wire x1="41.91" y1="63.5" x2="40.64" y2="62.23" width="0.254" layer="1"/>
<wire x1="37.9476" y1="61.9506" x2="37.9476" y2="60.0075" width="0.254" layer="1"/>
<wire x1="37.9476" y1="60.0075" x2="37.934" y2="59.944" width="0.254" layer="1"/>
<wire x1="37.9476" y1="61.9506" x2="37.934" y2="61.976" width="0.254" layer="1"/>
<wire x1="40.5765" y1="60.0075" x2="38.0619" y2="60.0075" width="0.254" layer="1"/>
<wire x1="38.0619" y1="60.0075" x2="37.934" y2="59.944" width="0.254" layer="1"/>
<wire x1="40.5765" y1="60.0075" x2="40.64" y2="59.944" width="0.254" layer="1"/>
<wire x1="40.5765" y1="60.1218" x2="40.5765" y2="62.1792" width="0.254" layer="1"/>
<wire x1="40.5765" y1="62.1792" x2="40.64" y2="62.23" width="0.254" layer="1"/>
<wire x1="40.5765" y1="60.1218" x2="40.64" y2="59.944" width="0.254" layer="1"/>
<wire x1="34.6329" y1="34.29" x2="34.29" y2="34.29" width="0.254" layer="16"/>
<wire x1="36.4617" y1="36.1188" x2="34.6329" y2="34.29" width="0.254" layer="16"/>
<wire x1="40.005" y1="36.1188" x2="36.4617" y2="36.1188" width="0.254" layer="16"/>
<wire x1="41.8338" y1="34.29" x2="40.005" y2="36.1188" width="0.254" layer="16"/>
<wire x1="41.8338" y1="34.29" x2="41.91" y2="34.29" width="0.254" layer="16"/>
<wire x1="40.6908" y1="36.9189" x2="40.6908" y2="59.8932" width="0.254" layer="16"/>
<wire x1="40.005" y1="36.2331" x2="40.6908" y2="36.9189" width="0.254" layer="16"/>
<wire x1="40.6908" y1="59.8932" x2="40.64" y2="59.944" width="0.254" layer="16"/>
<wire x1="40.005" y1="36.2331" x2="40.005" y2="36.1188" width="0.254" layer="16"/>
</signal>
<signal name="LED_EN">
<contactref element="JP1" pad="1"/>
<contactref element="J2" pad="15B_B"/>
<contactref element="J2" pad="15A_A"/>
<wire x1="41.91" y1="65.786" x2="40.894" y2="65.786" width="0.254" layer="1"/>
<wire x1="40.894" y1="65.786" x2="39.37" y2="67.31" width="0.254" layer="1"/>
<wire x1="39.4335" y1="67.3227" x2="39.4335" y2="69.8373" width="0.254" layer="1"/>
<wire x1="39.4335" y1="69.8373" x2="39.37" y2="69.85" width="0.254" layer="1"/>
<wire x1="39.4335" y1="67.3227" x2="39.37" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="APA_MISO">
<contactref element="J1" pad="12A"/>
<contactref element="J1" pad="12B"/>
<wire x1="31.7754" y1="39.4335" x2="31.7754" y2="41.8338" width="0.254" layer="1"/>
<wire x1="31.7754" y1="41.8338" x2="31.75" y2="41.91" width="0.254" layer="1"/>
<wire x1="31.7754" y1="39.4335" x2="31.75" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="SD_SCK">
<contactref element="J6" pad="5"/>
<contactref element="J2" pad="18B_B"/>
<contactref element="J2" pad="18A_A"/>
<wire x1="40.2336" y1="48.5775" x2="43.5483" y2="48.5775" width="0.254" layer="1"/>
<wire x1="21.6027" y1="67.2084" x2="40.2336" y2="48.5775" width="0.254" layer="1"/>
<wire x1="43.5483" y1="48.5775" x2="43.66" y2="48.542" width="0.254" layer="1"/>
<wire x1="21.6027" y1="67.2084" x2="21.59" y2="67.31" width="0.254" layer="1"/>
<wire x1="21.6027" y1="67.437" x2="21.6027" y2="69.8373" width="0.254" layer="1"/>
<wire x1="21.6027" y1="69.8373" x2="21.59" y2="69.85" width="0.254" layer="1"/>
<wire x1="21.6027" y1="67.437" x2="21.59" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="SD_MOSI">
<contactref element="J6" pad="3"/>
<contactref element="J2" pad="23A"/>
<contactref element="J2" pad="23B"/>
<wire x1="44.6913" y1="50.6349" x2="43.6626" y2="50.6349" width="0.254" layer="1"/>
<wire x1="45.1485" y1="50.1777" x2="44.6913" y2="50.6349" width="0.254" layer="1"/>
<wire x1="45.1485" y1="45.1485" x2="45.1485" y2="50.1777" width="0.254" layer="1"/>
<wire x1="44.4627" y1="44.4627" x2="45.1485" y2="45.1485" width="0.254" layer="1"/>
<wire x1="42.1767" y1="44.4627" x2="44.4627" y2="44.4627" width="0.254" layer="1"/>
<wire x1="36.0045" y1="50.6349" x2="42.1767" y2="44.4627" width="0.254" layer="1"/>
<wire x1="31.4325" y1="50.6349" x2="36.0045" y2="50.6349" width="0.254" layer="1"/>
<wire x1="16.002" y1="66.0654" x2="31.4325" y2="50.6349" width="0.254" layer="1"/>
<wire x1="5.0292" y1="66.0654" x2="16.002" y2="66.0654" width="0.254" layer="1"/>
<wire x1="3.8862" y1="67.2084" x2="5.0292" y2="66.0654" width="0.254" layer="1"/>
<wire x1="43.6626" y1="50.6349" x2="43.66" y2="50.742" width="0.254" layer="1"/>
<wire x1="3.8862" y1="67.2084" x2="3.81" y2="67.31" width="0.254" layer="1"/>
<wire x1="3.7719" y1="67.437" x2="3.7719" y2="69.8373" width="0.254" layer="1"/>
<wire x1="3.7719" y1="69.8373" x2="3.81" y2="69.85" width="0.254" layer="1"/>
<wire x1="3.7719" y1="67.437" x2="3.81" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="SD_MISO">
<contactref element="J6" pad="7"/>
<contactref element="J2" pad="19A_A"/>
<contactref element="J2" pad="19B_B"/>
<wire x1="42.6339" y1="46.4058" x2="43.5483" y2="46.4058" width="0.254" layer="1"/>
<wire x1="42.291" y1="46.7487" x2="42.6339" y2="46.4058" width="0.254" layer="1"/>
<wire x1="42.291" y1="59.7789" x2="42.291" y2="46.7487" width="0.254" layer="16"/>
<wire x1="40.9194" y1="61.1505" x2="42.291" y2="59.7789" width="0.254" layer="16"/>
<wire x1="40.2336" y1="61.1505" x2="40.9194" y2="61.1505" width="0.254" layer="16"/>
<wire x1="38.0619" y1="63.3222" x2="40.2336" y2="61.1505" width="0.254" layer="16"/>
<wire x1="38.0619" y1="72.009" x2="38.0619" y2="63.3222" width="0.254" layer="16"/>
<wire x1="37.3761" y1="72.6948" x2="38.0619" y2="72.009" width="0.254" layer="16"/>
<wire x1="21.1455" y1="72.6948" x2="37.3761" y2="72.6948" width="0.254" layer="16"/>
<wire x1="19.0881" y1="70.6374" x2="21.1455" y2="72.6948" width="0.254" layer="16"/>
<wire x1="19.0881" y1="69.9516" x2="19.0881" y2="70.6374" width="0.254" layer="16"/>
<wire x1="43.5483" y1="46.4058" x2="43.66" y2="46.342" width="0.254" layer="1"/>
<wire x1="19.0881" y1="69.9516" x2="19.05" y2="69.85" width="0.254" layer="16"/>
<wire x1="19.0881" y1="69.8373" x2="19.0881" y2="67.3227" width="0.254" layer="1"/>
<wire x1="19.0881" y1="67.3227" x2="19.05" y2="67.31" width="0.254" layer="1"/>
<wire x1="19.0881" y1="69.8373" x2="19.05" y2="69.85" width="0.254" layer="1"/>
<via x="42.291" y="46.7487" extent="1-16" drill="0.3302"/>
</signal>
<signal name="SD_CS">
<contactref element="J6" pad="2"/>
<contactref element="J2" pad="5B"/>
<contactref element="J2" pad="5A"/>
<wire x1="39.7764" y1="51.8922" x2="43.2054" y2="51.8922" width="0.254" layer="1"/>
<wire x1="32.8041" y1="58.8645" x2="39.7764" y2="51.8922" width="0.254" layer="1"/>
<wire x1="32.5755" y1="58.8645" x2="32.8041" y2="58.8645" width="0.254" layer="1"/>
<wire x1="24.13" y1="67.31" x2="32.5755" y2="58.8645" width="0.254" layer="1"/>
<wire x1="43.2054" y1="51.8922" x2="43.26" y2="51.842" width="0.254" layer="1"/>
<wire x1="24.1173" y1="67.3227" x2="24.1173" y2="69.8373" width="0.254" layer="1"/>
<wire x1="24.1173" y1="69.8373" x2="24.13" y2="69.85" width="0.254" layer="1"/>
<wire x1="24.1173" y1="67.3227" x2="24.13" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="OE_PWM">
<contactref element="IC6" pad="12"/>
<contactref element="IC6" pad="13"/>
<contactref element="J1" pad="33A"/>
<contactref element="J1" pad="33B"/>
<wire x1="19.0881" y1="39.4335" x2="19.0881" y2="41.8338" width="0.254" layer="1"/>
<wire x1="19.0881" y1="41.8338" x2="19.05" y2="41.91" width="0.254" layer="1"/>
<wire x1="19.0881" y1="39.4335" x2="19.05" y2="39.37" width="0.254" layer="1"/>
<wire x1="13.1445" y1="49.4919" x2="10.7442" y2="49.4919" width="0.254" layer="1"/>
<wire x1="10.7442" y1="49.4919" x2="10.668" y2="49.53" width="0.254" layer="1"/>
<wire x1="13.1445" y1="49.4919" x2="13.208" y2="49.53" width="0.254" layer="1"/>
<wire x1="18.9738" y1="43.5483" x2="18.9738" y2="41.9481" width="0.254" layer="1"/>
<wire x1="13.1445" y1="49.3776" x2="18.9738" y2="43.5483" width="0.254" layer="1"/>
<wire x1="18.9738" y1="41.9481" x2="19.05" y2="41.91" width="0.254" layer="1"/>
<wire x1="13.1445" y1="49.3776" x2="13.208" y2="49.53" width="0.254" layer="1"/>
</signal>
<signal name="OE_DMA">
<contactref element="IC6" pad="10"/>
<contactref element="IC6" pad="11"/>
<contactref element="J1" pad="32B"/>
<contactref element="J1" pad="32A"/>
<contactref element="JP2" pad="1"/>
<wire x1="15.748" y1="43.942" x2="16.07185" y2="43.61815" width="0.254" layer="1"/>
<wire x1="16.07185" y1="43.61815" x2="16.51" y2="43.18" width="0.254" layer="1"/>
<wire x1="16.51" y1="43.18" x2="16.51" y2="41.91" width="0.254" layer="1"/>
<wire x1="16.5735" y1="39.4335" x2="16.5735" y2="41.8338" width="0.254" layer="1"/>
<wire x1="16.5735" y1="41.8338" x2="16.51" y2="41.91" width="0.254" layer="1"/>
<wire x1="16.5735" y1="39.4335" x2="16.51" y2="39.37" width="0.254" layer="1"/>
<wire x1="8.1153" y1="49.4919" x2="5.6007" y2="49.4919" width="0.254" layer="1"/>
<wire x1="5.6007" y1="49.4919" x2="5.588" y2="49.53" width="0.254" layer="1"/>
<wire x1="8.1153" y1="49.4919" x2="8.128" y2="49.53" width="0.254" layer="1"/>
<wire x1="16.2306" y1="43.7769" x2="16.07185" y2="43.61815" width="0.254" layer="1"/>
<wire x1="16.2306" y1="44.1198" x2="16.2306" y2="43.7769" width="0.254" layer="1"/>
<wire x1="12.573" y1="47.7774" x2="16.2306" y2="44.1198" width="0.254" layer="1"/>
<wire x1="9.9441" y1="47.7774" x2="12.573" y2="47.7774" width="0.254" layer="1"/>
<wire x1="8.2296" y1="49.4919" x2="9.9441" y2="47.7774" width="0.254" layer="1"/>
<wire x1="8.2296" y1="49.4919" x2="8.128" y2="49.53" width="0.254" layer="1"/>
</signal>
<signal name="OE_SWITCH">
<contactref element="IC2" pad="5"/>
<contactref element="IC6" pad="2"/>
<wire x1="13.9446" y1="24.4602" x2="13.9446" y2="21.6027" width="0.254" layer="16"/>
<wire x1="12.9159" y1="25.4889" x2="13.9446" y2="24.4602" width="0.254" layer="16"/>
<wire x1="12.9159" y1="30.9753" x2="12.9159" y2="25.4889" width="0.254" layer="16"/>
<wire x1="15.2019" y1="33.2613" x2="12.9159" y2="30.9753" width="0.254" layer="16"/>
<wire x1="15.2019" y1="46.7487" x2="15.2019" y2="33.2613" width="0.254" layer="16"/>
<wire x1="17.145" y1="48.6918" x2="15.2019" y2="46.7487" width="0.254" layer="16"/>
<wire x1="17.145" y1="52.9209" x2="17.145" y2="48.6918" width="0.254" layer="16"/>
<wire x1="17.7165" y1="53.4924" x2="17.145" y2="52.9209" width="0.254" layer="16"/>
<wire x1="17.7165" y1="56.5785" x2="17.7165" y2="53.4924" width="0.254" layer="16"/>
<wire x1="18.288" y1="57.15" x2="17.7165" y2="56.5785" width="0.254" layer="16"/>
<wire x1="13.9446" y1="21.6027" x2="13.97" y2="21.59" width="0.254" layer="16"/>
</signal>
<signal name="BUFFER_CLK">
<contactref element="IC6" pad="6"/>
<contactref element="IC6" pad="4"/>
<contactref element="J1" pad="26B"/>
<contactref element="J1" pad="26A"/>
<wire x1="24.1173" y1="39.4335" x2="24.1173" y2="41.8338" width="0.254" layer="16"/>
<wire x1="24.1173" y1="41.8338" x2="24.13" y2="41.91" width="0.254" layer="16"/>
<wire x1="24.1173" y1="39.4335" x2="24.13" y2="39.37" width="0.254" layer="16"/>
<wire x1="8.4582" y1="57.15" x2="8.128" y2="57.15" width="0.254" layer="1"/>
<wire x1="10.287" y1="55.3212" x2="8.4582" y2="57.15" width="0.254" layer="1"/>
<wire x1="11.3157" y1="55.3212" x2="10.287" y2="55.3212" width="0.254" layer="1"/>
<wire x1="13.1445" y1="57.15" x2="11.3157" y2="55.3212" width="0.254" layer="1"/>
<wire x1="13.1445" y1="57.15" x2="13.208" y2="57.15" width="0.254" layer="1"/>
<wire x1="24.1173" y1="46.2915" x2="24.1173" y2="41.9481" width="0.254" layer="1"/>
<wire x1="21.9456" y1="48.4632" x2="24.1173" y2="46.2915" width="0.254" layer="1"/>
<wire x1="21.9456" y1="51.6636" x2="21.9456" y2="48.4632" width="0.254" layer="1"/>
<wire x1="18.288" y1="55.3212" x2="21.9456" y2="51.6636" width="0.254" layer="1"/>
<wire x1="14.9733" y1="55.3212" x2="18.288" y2="55.3212" width="0.254" layer="1"/>
<wire x1="13.2588" y1="57.0357" x2="14.9733" y2="55.3212" width="0.254" layer="1"/>
<wire x1="24.1173" y1="41.9481" x2="24.13" y2="41.91" width="0.254" layer="1"/>
<wire x1="13.2588" y1="57.0357" x2="13.208" y2="57.15" width="0.254" layer="1"/>
</signal>
<signal name="N$6">
<contactref element="J2" pad="CLKB"/>
<contactref element="J2" pad="CLKA"/>
<wire x1="46.9773" y1="67.3227" x2="46.9773" y2="69.8373" width="0.254" layer="1"/>
<wire x1="46.9773" y1="69.8373" x2="46.99" y2="69.85" width="0.254" layer="1"/>
<wire x1="46.9773" y1="67.3227" x2="46.99" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="N$7">
<contactref element="J2" pad="D0A"/>
<contactref element="J2" pad="D0B"/>
<wire x1="44.4627" y1="67.3227" x2="44.4627" y2="69.8373" width="0.254" layer="1"/>
<wire x1="44.4627" y1="69.8373" x2="44.45" y2="69.85" width="0.254" layer="1"/>
<wire x1="44.4627" y1="67.3227" x2="44.45" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="N$8">
<contactref element="J2" pad="D1A"/>
<contactref element="J2" pad="D1B"/>
<wire x1="41.9481" y1="67.3227" x2="41.9481" y2="69.8373" width="0.254" layer="1"/>
<wire x1="41.9481" y1="69.8373" x2="41.91" y2="69.85" width="0.254" layer="1"/>
<wire x1="41.9481" y1="67.3227" x2="41.91" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="N$14">
<contactref element="J2" pad="TXB"/>
<contactref element="J2" pad="TXA"/>
<wire x1="8.9154" y1="67.3227" x2="8.9154" y2="69.8373" width="0.254" layer="1"/>
<wire x1="8.9154" y1="69.8373" x2="8.89" y2="69.85" width="0.254" layer="1"/>
<wire x1="8.9154" y1="67.3227" x2="8.89" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="N$15">
<contactref element="J2" pad="RXB"/>
<contactref element="J2" pad="RXA"/>
<wire x1="11.43" y1="67.31" x2="11.43" y2="69.85" width="0.254" layer="1"/>
</signal>
<signal name="N$16">
<contactref element="J2" pad="17A_A"/>
<contactref element="J2" pad="17B_B"/>
<wire x1="26.6319" y1="67.3227" x2="26.6319" y2="69.8373" width="0.254" layer="1"/>
<wire x1="26.6319" y1="69.8373" x2="26.67" y2="69.85" width="0.254" layer="1"/>
<wire x1="26.6319" y1="67.3227" x2="26.67" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="N$17">
<contactref element="J2" pad="16A_A"/>
<contactref element="J2" pad="16_B"/>
<wire x1="29.2608" y1="67.3227" x2="29.2608" y2="69.8373" width="0.254" layer="1"/>
<wire x1="29.2608" y1="69.8373" x2="29.21" y2="69.85" width="0.254" layer="1"/>
<wire x1="29.2608" y1="67.3227" x2="29.21" y2="67.31" width="0.254" layer="1"/>
</signal>
<signal name="N$2">
<contactref element="J1" pad="CMD_B"/>
<contactref element="J1" pad="CMD_A"/>
<wire x1="44.4627" y1="39.4335" x2="44.4627" y2="41.8338" width="0.254" layer="1"/>
<wire x1="44.4627" y1="41.8338" x2="44.45" y2="41.91" width="0.254" layer="1"/>
<wire x1="44.4627" y1="39.4335" x2="44.45" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="N$3">
<contactref element="J1" pad="D3_A"/>
<contactref element="J1" pad="D3_B"/>
<wire x1="41.9481" y1="39.4335" x2="41.9481" y2="41.8338" width="0.254" layer="1"/>
<wire x1="41.9481" y1="41.8338" x2="41.91" y2="41.91" width="0.254" layer="1"/>
<wire x1="41.9481" y1="39.4335" x2="41.91" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="N$5">
<contactref element="J1" pad="D2A"/>
<contactref element="J1" pad="D2B"/>
<wire x1="39.4335" y1="39.4335" x2="39.4335" y2="41.8338" width="0.254" layer="1"/>
<wire x1="39.4335" y1="41.8338" x2="39.37" y2="41.91" width="0.254" layer="1"/>
<wire x1="39.4335" y1="39.4335" x2="39.37" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="N$9">
<contactref element="J1" pad="VNA"/>
<contactref element="J1" pad="VNB"/>
<wire x1="8.9154" y1="39.4335" x2="8.9154" y2="41.8338" width="0.254" layer="1"/>
<wire x1="8.9154" y1="41.8338" x2="8.89" y2="41.91" width="0.254" layer="1"/>
<wire x1="8.9154" y1="39.4335" x2="8.89" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="N$10">
<contactref element="J1" pad="VPA"/>
<contactref element="J1" pad="VPB"/>
<wire x1="6.4008" y1="39.4335" x2="6.4008" y2="41.8338" width="0.254" layer="1"/>
<wire x1="6.4008" y1="41.8338" x2="6.35" y2="41.91" width="0.254" layer="1"/>
<wire x1="6.4008" y1="39.4335" x2="6.35" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="N$11">
<contactref element="J1" pad="34B"/>
<contactref element="J1" pad="34A"/>
<wire x1="11.43" y1="39.37" x2="11.43" y2="41.91" width="0.254" layer="1"/>
</signal>
<signal name="N$13">
<contactref element="J1" pad="ENB"/>
<contactref element="J1" pad="ENA"/>
<wire x1="3.7719" y1="39.4335" x2="3.7719" y2="41.8338" width="0.254" layer="1"/>
<wire x1="3.7719" y1="41.8338" x2="3.81" y2="41.91" width="0.254" layer="1"/>
<wire x1="3.7719" y1="39.4335" x2="3.81" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="APA_MOSI">
<contactref element="J1" pad="13B_B"/>
<contactref element="J1" pad="13A_A"/>
<contactref element="IC5" pad="1"/>
<wire x1="44.1198" y1="34.29" x2="44.45" y2="34.29" width="0.254" layer="1"/>
<wire x1="40.3479" y1="38.0619" x2="44.1198" y2="34.29" width="0.254" layer="1"/>
<wire x1="38.1762" y1="38.0619" x2="40.3479" y2="38.0619" width="0.254" layer="1"/>
<wire x1="36.9189" y1="39.3192" x2="38.1762" y2="38.0619" width="0.254" layer="1"/>
<wire x1="36.9189" y1="39.3192" x2="36.83" y2="39.37" width="0.254" layer="1"/>
<wire x1="36.8046" y1="39.4335" x2="36.8046" y2="41.8338" width="0.254" layer="1"/>
<wire x1="36.8046" y1="41.8338" x2="36.83" y2="41.91" width="0.254" layer="1"/>
<wire x1="36.8046" y1="39.4335" x2="36.83" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="APA_SCK">
<contactref element="J1" pad="14B_B"/>
<contactref element="J1" pad="14A_A"/>
<contactref element="IC5" pad="4"/>
<wire x1="36.576" y1="34.29" x2="36.83" y2="34.29" width="0.254" layer="1"/>
<wire x1="32.8041" y1="38.0619" x2="36.576" y2="34.29" width="0.254" layer="1"/>
<wire x1="30.5181" y1="38.0619" x2="32.8041" y2="38.0619" width="0.254" layer="1"/>
<wire x1="29.21" y1="39.37" x2="30.5181" y2="38.0619" width="0.254" layer="1"/>
<wire x1="29.2608" y1="39.4335" x2="29.2608" y2="41.8338" width="0.254" layer="1"/>
<wire x1="29.2608" y1="41.8338" x2="29.21" y2="41.91" width="0.254" layer="1"/>
<wire x1="29.2608" y1="39.4335" x2="29.21" y2="39.37" width="0.254" layer="1"/>
</signal>
<signal name="N$1">
<contactref element="J1" pad="35A"/>
<contactref element="J1" pad="35B"/>
<contactref element="JP2" pad="2"/>
<wire x1="14.732" y1="43.942" x2="13.97" y2="43.18" width="0.254" layer="1"/>
<wire x1="13.97" y1="43.18" x2="13.97" y2="41.91" width="0.254" layer="1"/>
<wire x1="13.9446" y1="39.4335" x2="13.9446" y2="41.8338" width="0.254" layer="1"/>
<wire x1="13.9446" y1="41.8338" x2="13.97" y2="41.91" width="0.254" layer="1"/>
<wire x1="13.9446" y1="39.4335" x2="13.97" y2="39.37" width="0.254" layer="1"/>
</signal>
</signals>
</board>
</drawing>
<compatibility>
<note version="6.3" minversion="6.2.2" severity="warning">
Since Version 6.2.2 text objects can contain more than one line,
which will not be processed correctly with this version.
</note>
<note version="8.2" severity="warning">
Since Version 8.2, EAGLE supports online libraries. The ids
of those online libraries will not be understood (or retained)
with this version.
</note>
<note version="8.3" severity="warning">
Since Version 8.3, EAGLE supports URNs for individual library
assets (packages, symbols, and devices). The URNs of those assets
will not be understood (or retained) with this version.
</note>
<note version="8.3" severity="warning">
Since Version 8.3, EAGLE supports the association of 3D packages
with devices in libraries, schematics, and board files. Those 3D
packages will not be understood (or retained) with this version.
</note>
</compatibility>
</eagle>


text:
/*
 *     Copyright 2020 The Dragonfly Authors
 *
 * 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.
 */

package worker

import (
	"fmt"
	"time"

	"d7y.io/dragonfly/v2/pkg/safe"

	"k8s.io/client-go/util/workqueue"

	"d7y.io/dragonfly/v2/internal/dfcodes"
	logger "d7y.io/dragonfly/v2/internal/dflog"
	scheduler2 "d7y.io/dragonfly/v2/pkg/rpc/scheduler"
	"d7y.io/dragonfly/v2/scheduler/service"
	"d7y.io/dragonfly/v2/scheduler/types"
)

type JobType int8

type Worker struct {
	scheduleQueue          workqueue.Interface
	updatePieceResultQueue chan *scheduler2.PieceResult
	sender                 ISender
	stopCh                 <-chan struct{}
	sendJob                func(*types.PeerTask)

	schedulerService *service.SchedulerService
}

var _ IWorker = (*Worker)(nil)

func NewWorker(schedulerService *service.SchedulerService, sender ISender, sendJod func(*types.PeerTask), stop <-chan struct{}) *Worker {
	return &Worker{
		scheduleQueue:          workqueue.New(),
		updatePieceResultQueue: make(chan *scheduler2.PieceResult, 100000),
		stopCh:                 stop,
		sender:                 sender,
		schedulerService:       schedulerService,
		sendJob:                sendJod,
	}
}

func (w *Worker) Serve() {
	go safe.Call(w.doScheduleWorker)
	go safe.Call(w.doUpdatePieceResultWorker)
}

func (w *Worker) Stop() {
	if w == nil {
		return
	}
	w.scheduleQueue.ShutDown()
	close(w.updatePieceResultQueue)
}

func (w *Worker) ReceiveUpdatePieceResult(pr *scheduler2.PieceResult) {
	w.updatePieceResultQueue <- pr
}

func (w *Worker) doUpdatePieceResultWorker() {
	for {
		pr, ok := <-w.updatePieceResultQueue
		if !ok {
			return
		}
		peerTask, needSchedule, err := w.UpdatePieceResult(pr)
		if needSchedule {
			w.sendJob(peerTask)
		}

		if err != nil {
			logger.Errorf("[%s][%s]: update piece result failed %v", pr.TaskId, pr.SrcPid, err.Error())
		}
	}
}

func (w *Worker) UpdatePieceResult(pr *scheduler2.PieceResult) (peerTask *types.PeerTask, needSchedule bool, err error) {
	if pr == nil {
		return
	}

	if w.processErrorCode(pr) {
		return
	}

	pt := w.schedulerService.TaskManager.PeerTask
	peerTask, _ = pt.Get(pr.SrcPid)
	if peerTask == nil {
		task, _ := w.schedulerService.TaskManager.Get(pr.TaskId)
		if task != nil {
			peerTask = pt.AddFake(pr.SrcPid, task)
		} else {
			err = fmt.Errorf("[%s][%s]: task not exited", pr.TaskId, pr.SrcPid)
			logger.Errorf(err.Error())
			return
		}
	}
	defer pt.Update(peerTask)

	var dstPeerTask *types.PeerTask
	if pr.DstPid == "" {
		if peerTask.GetParent() == nil {
			peerTask.SetNodeStatus(types.PeerTaskStatusNeedParent)
			needSchedule = true
			pt.RefreshDownloadMonitor(peerTask)
			return
		}
	} else {
		dstPeerTask, _ = pt.Get(pr.DstPid)
		if dstPeerTask == nil {
			dstPeerTask = pt.AddFake(pr.DstPid, peerTask.Task)
		}
	}

	if pr.PieceNum < 0 {
		if peerTask.GetParent() != nil {
			w.sendScheduleResult(peerTask)
		}
		return
	}

	peerTask.AddPieceStatus(pr)
	status := peerTask.GetNodeStatus()
	if peerTask.Success || status == types.PeerTaskStatusDone || peerTask.IsDown() {
		return
	}
	if dstPeerTask != nil && peerTask.GetParent() == nil {
		peerTask.SetNodeStatus(types.PeerTaskStatusAddParent, dstPeerTask)
		needSchedule = true
	} else if status == types.PeerTaskStatusHealth && w.schedulerService.Scheduler.IsNodeBad(peerTask) {
		peerTask.SetNodeStatus(types.PeerTaskStatusBadNode)
		needSchedule = true
	} else if status == types.PeerTaskStatusHealth && w.schedulerService.Scheduler.NeedAdjustParent(peerTask) {
		peerTask.SetNodeStatus(types.PeerTaskStatusNeedAdjustNode)
		needSchedule = true
	}

	pt.RefreshDownloadMonitor(peerTask)

	return
}

func (w *Worker) ReceiveJob(peerTask *types.PeerTask) {
	logger.Debugf("doScheduleWorker begin add [%s]", peerTask.Pid)
	w.scheduleQueue.Add(peerTask)
}

func (w *Worker) sendJobLater(peerTask *types.PeerTask) {
	w.schedulerService.TaskManager.PeerTask.RefreshDownloadMonitor(peerTask)
}

func (w *Worker) doScheduleWorker() {
	defer logger.Debugf("doScheduleWorker return")
	for {
		logger.Debugf("doScheduleWorker begin get")
		job, shutdown := w.scheduleQueue.Get()
		logger.Debugf("doScheduleWorker end get")
		if shutdown {
			return
		}
		peerTask, _ := job.(*types.PeerTask)
		w.doSchedule(peerTask)
		logger.Debugf("doScheduleWorker begin done [%s]", peerTask.Pid)
		w.scheduleQueue.Done(job)
		logger.Debugf("doScheduleWorker end done [%s]", peerTask.Pid)
	}
}

func (w *Worker) doSchedule(peerTask *types.PeerTask) {
	if peerTask == nil {
		return
	}

	startTm := time.Now()
	status := peerTask.GetNodeStatus()
	logger.Debugf("[%s][%s]: begin do schedule [%d]", peerTask.Task.TaskID, peerTask.Pid, status)
	defer func() {
		err := recover()
		if err != nil {
			logger.Errorf("[%s][%s]: do schedule panic: %v", peerTask.Task.TaskID, peerTask.Pid, err)
		}
		logger.Infof("[%s][%s]: end do schedule [%d] cost: %d", peerTask.Task.TaskID, peerTask.Pid, status, time.Now().Sub(startTm).Nanoseconds())
	}()

	switch status {
	case types.PeerTaskStatusAddParent:
		parent, _ := peerTask.GetJobData().(*types.PeerTask)
		if parent == nil {
			peerTask.SetNodeStatusHealth(types.PeerTaskStatusAddParent)
			return
		}
		peerTask.AddParent(parent, 1)
		peerTask.SetNodeStatusHealth(types.PeerTaskStatusAddParent)
		return
	case types.PeerTaskStatusNeedParent:
		parent, _, err := w.schedulerService.Scheduler.ScheduleParent(peerTask)
		if err != nil {
			logger.Debugf("[%s][%s]: schedule parent failed: %v", peerTask.Task.TaskID, peerTask.Pid, err)
		}
		// retry scheduler parent later when this is no parent
		if parent == nil || err != nil {
			w.sendJobLater(peerTask)
		} else {
			w.sendScheduleResult(peerTask)
			peerTask.SetNodeStatusHealth(types.PeerTaskStatusNeedParent)
		}
		w.schedulerService.TaskManager.PeerTask.RefreshDownloadMonitor(peerTask)
	case types.PeerTaskStatusNeedChildren:
		children, err := w.schedulerService.Scheduler.ScheduleChildren(peerTask)
		if err != nil {
			logger.Debugf("[%s][%s]: schedule children failed: %v", peerTask.Task.TaskID, peerTask.Pid, err)
			return
		}
		for i := range children {
			if children[i].GetParent() != nil {
				w.sendScheduleResult(children[i])
			} else {
				children[i].SetNodeStatus(types.PeerTaskStatusNeedParent)
				w.sendJob(children[i])
			}
		}
		peerTask.SetNodeStatusHealth(types.PeerTaskStatusNeedChildren)

	case types.PeerTaskStatusBadNode:
		adjustNodes, err := w.schedulerService.Scheduler.ScheduleBadNode(peerTask)
		if err != nil {
			logger.Debugf("[%s][%s]: schedule bad node failed: %v", peerTask.Task.TaskID, peerTask.Pid, err)
			w.sendJobLater(peerTask)
			return
		}
		for i := range adjustNodes {
			if adjustNodes[i].GetParent() != nil {
				w.sendScheduleResult(adjustNodes[i])
			} else {
				adjustNodes[i].SetNodeStatus(types.PeerTaskStatusNeedParent)
				w.sendJob(adjustNodes[i])
			}
		}
		if peerTask.GetParent() == nil {
			peerTask.SetNodeStatus(types.PeerTaskStatusNeedParent)
			w.sendJobLater(peerTask)
		}

	case types.PeerTaskStatusNeedAdjustNode:
		_, _, err := w.schedulerService.Scheduler.ScheduleAdjustParentNode(peerTask)
		if err != nil {
			logger.Debugf("[%s][%s]: schedule adjust node failed: %v", peerTask.Task.TaskID, peerTask.Pid, err)
			w.sendJobLater(peerTask)
			return
		}
		w.sendScheduleResult(peerTask)
		peerTask.SetNodeStatusHealth(types.PeerTaskStatusNeedAdjustNode)

	case types.PeerTaskStatusNeedCheckNode:
		if w.schedulerService.Scheduler.IsNodeBad(peerTask) && peerTask.GetSubTreeNodesNum() > 1 {
			adjustNodes, err := w.schedulerService.Scheduler.ScheduleBadNode(peerTask)
			if err != nil {
				logger.Debugf("[%s][%s]: schedule bad node failed: %v", peerTask.Task.TaskID, peerTask.Pid, err)
				peerTask.SetNodeStatus(types.PeerTaskStatusBadNode)
				w.sendJobLater(peerTask)
				return
			}
			for i := range adjustNodes {
				if adjustNodes[i].GetParent() != nil {
					w.sendScheduleResult(adjustNodes[i])
				} else {
					adjustNodes[i].SetNodeStatus(types.PeerTaskStatusNeedParent)
					w.sendJob(adjustNodes[i])
				}
			}
			peerTask.SetNodeStatusHealth(types.PeerTaskStatusNeedCheckNode)
		} else if w.schedulerService.Scheduler.NeedAdjustParent(peerTask) {
			_, _, err := w.schedulerService.Scheduler.ScheduleAdjustParentNode(peerTask)
			if err != nil {
				logger.Debugf("[%s][%s]: schedule adjust node failed: %v", peerTask.Task.TaskID, peerTask.Pid, err)
				return
			}
			w.sendScheduleResult(peerTask)
			peerTask.SetNodeStatusHealth(types.PeerTaskStatusNeedCheckNode)
		}

	case types.PeerTaskStatusDone:
		parent, err := w.schedulerService.Scheduler.ScheduleDone(peerTask)
		if err != nil {
			logger.Debugf("[%s][%s]: schedule adjust node failed: %v", peerTask.Task.TaskID, peerTask.Pid, err)
			w.sendJobLater(peerTask)
			return
		}
		if parent != nil {
			parent.SetNodeStatus(types.PeerTaskStatusNeedChildren)
			w.sendJob(parent)
		}
		peerTask.SetNodeStatusHealth(types.PeerTaskStatusDone)

	case types.PeerTaskStatusLeaveNode, types.PeerTaskStatusNodeGone:
		adjustNodes, err := w.schedulerService.Scheduler.ScheduleLeaveNode(peerTask)
		if err != nil {
			logger.Debugf("[%s][%s]: schedule adjust node failed: %v", peerTask.Task.TaskID, peerTask.Pid, err)
			w.sendJobLater(peerTask)
			return
		}
		w.schedulerService.TaskManager.PeerTask.Delete(peerTask.Pid)
		logger.Debugf("[%s][%s]: PeerTaskStatusLeaveNode", peerTask.Task.TaskID, peerTask.Pid)
		for i := range adjustNodes {
			if adjustNodes[i].GetParent() != nil {
				w.sendScheduleResult(adjustNodes[i])
			} else {
				adjustNodes[i].SetNodeStatus(types.PeerTaskStatusNeedParent)
				w.sendJob(adjustNodes[i])
			}
		}

		// delete from manager
		w.schedulerService.TaskManager.PeerTask.Delete(peerTask.Pid)
		// delete from host
		peerTask.Host.DeletePeerTask(peerTask.Pid)
	}
	return
}

func (w *Worker) sendScheduleResult(peerTask *types.PeerTask) {
	if peerTask == nil {
		return
	}
	parent := "nil"
	if peerTask.GetParent() != nil && peerTask.GetParent().DstPeerTask != nil {
		parent = peerTask.GetParent().DstPeerTask.Pid
	}
	logger.Infof("[%s][%s]: sendScheduleResult parent[%s] active time[%d] deep [%d]", peerTask.Task.TaskID, peerTask.Pid, parent, time.Now().UnixNano()-peerTask.GetStartTime(), peerTask.GetDeep())
	w.sender.Send(peerTask)
	return
}

func (w *Worker) processErrorCode(pr *scheduler2.PieceResult) (stop bool) {
	code := pr.Code

	switch code {
	case dfcodes.Success:
		return
	case dfcodes.PeerTaskNotFound:
		peerTask, _ := w.schedulerService.TaskManager.PeerTask.Get(pr.SrcPid)
		if peerTask != nil {
			parent := peerTask.GetParent()
			if parent != nil && parent.DstPeerTask != nil {
				pNode := parent.DstPeerTask
				pNode.SetNodeStatus(types.PeerTaskStatusLeaveNode)
				w.sendJob(pNode)
			}
			peerTask.SetNodeStatus(types.PeerTaskStatusNeedParent)
			w.sendJob(peerTask)
		}
		return true
	case dfcodes.ClientPieceRequestFail, dfcodes.ClientPieceDownloadFail:
		peerTask, _ := w.schedulerService.TaskManager.PeerTask.Get(pr.SrcPid)
		if peerTask != nil {
			peerTask.SetNodeStatus(types.PeerTaskStatusNeedParent)
			w.sendJob(peerTask)
		}
		return true
	case dfcodes.CdnTaskNotFound, dfcodes.CdnError, dfcodes.CdnTaskRegistryFail:
		peerTask, _ := w.schedulerService.TaskManager.PeerTask.Get(pr.SrcPid)
		if peerTask != nil {
			peerTask.SetNodeStatus(types.PeerTaskStatusNeedParent)
			w.sendJob(peerTask)
			task := peerTask.Task
			if task != nil {
				if task.CDNError != nil {
					go safe.Call(func() { peerTask.SendError(task.CDNError) })
				} else {
					w.schedulerService.CDNManager.TriggerTask(task, w.schedulerService.TaskManager.PeerTask.CDNCallback)
				}
			}
		}
		return true
	case dfcodes.UnknownError:
		return true
	}

	return
}

license_type: permissive

branch_name: refs/heads/main

extension: go


text:
#include <Math/hash.h>
#include <Common/primitive_type.h>

#include <gtest/gtest.h>

#include <vector>
#include <limits>
#include <cstddef>
#include <string>

using namespace ph;
using namespace ph::math;

TEST(HashTest, MurmurHash3_32_Test)
{
	auto test_string =
		[](const std::string& s, uint32 seed, uint32 expected)
		{
			uint32 hash = murmur3_32(s.c_str(), s.length(), seed);
			EXPECT_EQ(hash, expected);
		};

	auto test_array =
		[](const std::vector<uint8>& s, uint32 seed, uint32 expected)
		{
			uint32 hash = murmur3_32(s.data(), s.size(), seed);
			EXPECT_EQ(hash, expected);
		};

	// Test cases are from `vladimirgamalyan`'s test case.

	// With zero data and zero seed, everything becomes zero
	test_array({}, 0, 0);

	// Ignores nearly all the math
	test_array({}, 1, 0x514E28B7);

	// Make sure your seed uses unsigned 32-bit math
	test_array({}, 0xFFFFFFFF, 0x81F16F39);

	// Make sure 4-byte blocks use unsigned math
	test_array({0xFF, 0xFF, 0xFF, 0xFF}, 0, 0x76293B50);

	// Endian order. A `uint32` block should end up as 0x87654321
	test_array({0x21, 0x43, 0x65, 0x87}, 0, 0xF55B516B);

	// Special seed value eliminates initial key with xor
	test_array({0x21, 0x43, 0x65, 0x87}, 0x5082EDEE, 0x2362F9DE);

	// Only three bytes. Should end up as 0x654321
	test_array({0x21, 0x43, 0x65}, 0, 0x7E4A8634);

	// Only two bytes. Should end up as 0x4321
	test_array({0x21, 0x43}, 0, 0xA0F7B07A);

	// Only one byte. Should end up as 0x21
	test_array({0x21}, 0, 0x72661CF4);

	// Make sure compiler doesn't see zero and convert to null
	test_array({0x00, 0x00, 0x00, 0x00}, 0, 0x2362F9DE);

	test_array({0x00, 0x00, 0x00}, 0, 0x85F0B427);
	test_array({0x00, 0x00}, 0, 0x30F4C306);
	test_array({0x00}, 0, 0x514E28B7);

	// Empty string with zero seed should give zero
	test_string("", 0, 0);

	test_string("", 1, 0x514E28B7);

	// Make sure seed value is handled unsigned
	test_string("", 0xFFFFFFFF, 0x81F16F39);

	// One full block
	test_string("aaaa", 0x9747B28C, 0x5A97808A);

	// Three characters
	test_string("aaa", 0x9747B28C, 0x283E0130);

	// Two characters
	test_string("aa", 0x9747B28C, 0x5D211726);

	// One character
	test_string("a", 0x9747B28C, 0x7FA09EA6);

	// Endian order within the blocks
	test_string("abcd", 0x9747B28C, 0xF0478627);
	test_string("abc", 0x9747B28C, 0xC84A62DD);
	test_string("ab", 0x9747B28C, 0x74875592);
	test_string("a", 0x9747B28C, 0x7FA09EA6);

	test_string("Hello, world!", 0x9747B28C, 0x24884CBA);

	test_string(
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		0x9747B28C,
		0x37405BDC);

	test_string("abc", 0, 0xB3DD93FA);
	test_string("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 0, 0xEE925B90);
	test_string("The quick brown fox jumps over the lazy dog", 0x9747B28C, 0x2FA826CD);
}

//TEST(HashTest, MurmurHash3_32_CollisionTest)
//{
//	std::size_t numCollisions = 0;
//
//	std::vector<bool> isHashUsed(std::numeric_limits<uint32>::max(), false);
//	for(uint32 value = 0; value < isHashUsed.size(); ++value)
//	{
//		const auto hash = static_cast<uint32>(murmur3_32(&value, 1, 42));
//		/*ASSERT_FALSE(isHashUsed[hash]) <<
//			"(hash collision found: value = " << value << ", hash = " << hash << ")";*/
//
//		if(isHashUsed[hash])
//		{
//			++numCollisions;
//		}
//
//		isHashUsed[hash] = true;
//	}
//
//	EXPECT_EQ(numCollisions, 0);
//}

license: MIT

branch_name: refs/heads/master

gha_license_id: MIT

extension: cpp