3 * A general hub miner class
5 * @author Roland Haeder <webmaster@shipsimu.org>
7 * @copyright Copyright (c) 2011 - 2012 Miner Developer Team
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.shipsimu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 abstract class BaseHubMiner extends BaseHubSystem implements Updateable {
28 private $version = 'x.x';
31 * By default no miner is active
33 private $isActive = FALSE;
36 * All buffer queue instances (a FIFO)
38 private $bufferInstance = NULL;
41 * An array for initialized producers
43 private $producersInitialized = array();
46 * Stacker name for incoming queue
48 const STACKER_NAME_IN_QUEUE = 'in_queue';
51 * Stacker name for outcoming queue
53 const STACKER_NAME_OUT_QUEUE = 'out_queue';
56 * Maximum number of producers (2: test and real)
58 const MAX_PRODUCERS = 2;
61 * Protected constructor
63 * @param $className Name of the class
66 protected function __construct ($className) {
67 // Call parent constructor
68 parent::__construct($className);
75 * Initialize the miner generically
79 private function initMiner () {
80 // Add own instance to registry
81 Registry::getRegistry()->addInstance('miner', $this);
84 MinerStateFactory::createMinerStateInstanceByName('init');
90 * @return $version Version number of this miner
92 protected final function getVersion () {
93 return $this->version;
99 * @param $version Version number of this miner
102 protected final function setVersion ($version) {
103 $this->version = (string) $version;
107 * Checks whether the in-buffer queue is filled by comparing it's current
108 * amount of entries against a threshold.
110 * @return $isFilled Whether the in-buffer is filled
112 protected function isInBufferQueueFilled () {
114 $isFilled = ($this->bufferInstance->getStackCount(self::STACKER_NAME_IN_QUEUE) > $this->getConfigInstance()->getConfigEntry('miner_in_buffer_min_threshold'));
116 // And return the result
121 * This method fills the in-buffer with (a) test unit(s) which are mainly
122 * used for development of the crunching part. They must be enabled in
123 * configuration, or else your miner runs out of WUs and waits for more
126 * In this method we already know that the in-buffer is going depleted so
127 * no need to double-check it here.
131 abstract protected function fillInBufferQueueWithTestUnits ();
134 * This method fills the in-buffer with (real) WUs which will be crunched
135 * and the result be sent back to the key producer instance.
139 abstract protected function fillInBufferQueueWithWorkUnits ();
142 * Enables/disables the miner (just sets a flag)
144 * @param $version Version number of this miner
147 public final function enableIsActive ($isActive = TRUE) {
148 $this->isActive = (bool) $isActive;
152 * Determines whether the miner is active
154 * @return $isActive Whether the miner is active
156 public final function isActive () {
157 return $this->isActive;
161 * Initializes all buffer queues (mostly in/out). This method is demanded
162 * by the MinerHelper interface.
166 public function initBufferQueues () {
168 * Initialize both buffer queues, we can use the FIFO class here
169 * directly and encapsulate its method calls with protected methods.
171 $this->bufferInstance = ObjectFactory::createObjectByConfiguredName('miner_buffer_stacker_class');
173 // Initialize common stackers, like in/out
174 $this->bufferInstance->initStacks(array(
175 self::STACKER_NAME_IN_QUEUE,
176 self::STACKER_NAME_OUT_QUEUE
179 // Output debug message
180 self::createDebugInstance(__CLASS__)->debugOutput('MINER: All buffers are now initialized.');
184 * This method determines if the in-buffer is going to depleted and if so,
185 * it fetches more WUs from the network. If no WU can be fetched from the
186 * network and if enabled, a random test WU is being generated.
188 * This method is demanded from the MinerHelper interface.
192 public function doFetchWorkUnits () {
193 // Simply check if we have enough WUs left in the in-buffer queue (a FIFO)
194 if (!$this->isInBufferQueueFilled()) {
195 // The in-buffer queue needs filling, so head out and get some work
196 $this->fillInBufferQueueWithWorkUnits();
198 // Is the buffer still not filled and are test-packages allowed?
199 if ((!$this->isInBufferQueueFilled()) && ($this->getConfigInstance()->getConfigEntry('miner_test_units_enabled') == 'Y')) {
200 // Then fill the in-buffer with (one) test-unit(s)
201 $this->fillInBufferQueueWithTestUnits();
207 * Updates a given field with new value
209 * @param $fieldName Field to update
210 * @param $fieldValue New value to store
212 * @throws DatabaseUpdateSupportException If this class does not support database updates
213 * @todo Try to make this method more generic so we can move it in BaseFrameworkSystem
215 public function updateDatabaseField ($fieldName, $fieldValue) {
217 $this->partialStub('Unfinished!');
222 * Changes the state to 'booting' and shall be called after the block
223 * producer has been initialized.
225 * @param $producerInstance An instance of a BlockProducer class
228 public function blockProducerHasInitialized (BlockProducer $producerInstance) {
229 // Make sure the state is correct ('init')
230 $this->getStateInstance()->validateMinerStateIsInit();
232 // Mark given producer as initialized
233 $this->producersInitialized[$producerInstance->__toString()] = TRUE;
235 // Has all producers been initialized?
236 if (count($this->producersInitialized) == self::MAX_PRODUCERS) {
237 // Change it to 'booting'
238 MinerStateFactory::createMinerStateInstanceByName('booting');