Package freenet.support.api

Examples of freenet.support.api.LongCallback


     
    });
    respondOverallBulkOutputCapacityUsage = nodeConfig.getBoolean("probeOverallBulkOutputCapacityUsage");

    nodeConfig.register("identifier", -1, sortOrder++, true, true, "Node.probeIdentifierShort",
      "Node.probeIdentifierLong", new LongCallback() {
      @Override
      public Long get() {
        return probeIdentifier;
      }
View Full Code Here


        }
       
        // Max bucket size 5% of the total, minimum 32KB (one block, vast majority of buckets)
        long maxBucketSize = Math.max(32768, (defaultRamBucketPoolSize * 1024 * 1024) / 20);

        nodeConfig.register("maxRAMBucketSize", SizeUtil.formatSizeWithoutSpace(maxBucketSize), sortOrder++, true, false, "NodeClientCore.maxRAMBucketSize", "NodeClientCore.maxRAMBucketSizeLong", new LongCallback() {

            @Override
            public Long get() {
                return (tempBucketFactory == null ? 0 : tempBucketFactory.getMaxRAMBucketSize());
            }

            @Override
            public void set(Long val) throws InvalidConfigValueException {
                if (get().equals(val) || (tempBucketFactory == null))
                            return;
                tempBucketFactory.setMaxRAMBucketSize(val);
            }
        }, true);

        nodeConfig.register("RAMBucketPoolSize", defaultRamBucketPoolSize+"MiB", sortOrder++, true, false, "NodeClientCore.ramBucketPoolSize", "NodeClientCore.ramBucketPoolSizeLong", new LongCallback() {

            @Override
            public Long get() {
                return (tempBucketFactory == null ? 0 : tempBucketFactory.getMaxRamUsed());
            }

            @Override
            public void set(Long val) throws InvalidConfigValueException {
                if (get().equals(val) || (tempBucketFactory == null))
                            return;
                tempBucketFactory.setMaxRamUsed(val);
                updatePersistentRAFSpaceLimit();
            }
        }, true);

        nodeConfig.register("encryptTempBuckets", true, sortOrder++, true, false, "NodeClientCore.encryptTempBuckets", "NodeClientCore.encryptTempBucketsLong", new BooleanCallback() {

            @Override
            public Boolean get() {
                return (tempBucketFactory == null ? true : tempBucketFactory.isEncrypting());
            }

            @Override
            public void set(Boolean val) throws InvalidConfigValueException {
                if (get().equals(val) || (tempBucketFactory == null))
                            return;
                tempBucketFactory.setEncryption(val);
            }
        });
       
        initDiskSpaceLimits(nodeConfig, sortOrder);
       
        cryptoSecretTransient = new MasterSecret();
        tempBucketFactory = new TempBucketFactory(node.executor, tempFilenameGenerator, nodeConfig.getLong("maxRAMBucketSize"), nodeConfig.getLong("RAMBucketPoolSize"), node.fastWeakRandom, nodeConfig.getBoolean("encryptTempBuckets"), minDiskFreeShortTerm, cryptoSecretTransient);

        bandwidthStatsPutter = new PersistentStatsPutter();
       
    clientLayerPersister = new ClientLayerPersister(node.executor, node.ticker,
            node, this, persistentTempBucketFactory, tempBucketFactory, bandwidthStatsPutter);
   
    SemiOrderedShutdownHook shutdownHook = SemiOrderedShutdownHook.get();
   
    shutdownHook.addEarlyJob(new NativeThread("Shutdown database", NativeThread.HIGH_PRIORITY, true) {
       
        @Override
        public void realRun() {
            System.err.println("Stopping database jobs...");
            clientLayerPersister.shutdown();
        }
       
    });
   
        shutdownHook.addLateJob(new NativeThread("Close database", NativeThread.HIGH_PRIORITY, true) {

            @Override
            public void realRun() {
                if(NodeClientCore.this.node.hasPanicked()) return;
                System.out.println("Waiting for jobs to finish");
                clientLayerPersister.waitForIdleAndCheckpoint();
                System.out.println("Saved persistent requests to disk");
            }

        });
       
    archiveManager = new ArchiveManager(MAX_ARCHIVE_HANDLERS, MAX_CACHED_ARCHIVE_DATA, MAX_ARCHIVED_FILE_SIZE, MAX_CACHED_ELEMENTS, tempBucketFactory);

    healingQueue = new SimpleHealingQueue(
        new InsertContext(
            0, 2, 0, 0, new SimpleEventProducer(),
            false, Node.FORK_ON_CACHEABLE_DEFAULT, false, Compressor.DEFAULT_COMPRESSORDESCRIPTOR, 0, 0, InsertContext.CompatibilityMode.COMPAT_DEFAULT), RequestStarter.PREFETCH_PRIORITY_CLASS, 512 /* FIXME make configurable */);

    PooledFileRandomAccessBufferFactory raff =
        new PooledFileRandomAccessBufferFactory(persistentFilenameGenerator, node.fastWeakRandom);
    persistentDiskChecker =
        new DiskSpaceCheckingRandomAccessBufferFactory(raff, persistentTempDir.dir(),
                minDiskFreeLongTerm + tempBucketFactory.getMaxRamUsed());
    persistentRAFFactory = new MaybeEncryptedRandomAccessBufferFactory(persistentDiskChecker, nodeConfig.getBoolean("encryptPersistentTempBuckets"));
    persistentTempBucketFactory.setDiskSpaceChecker(persistentDiskChecker);
    HighLevelSimpleClient client = makeClient((short)0, false, false);
    FetchContext defaultFetchContext = client.getFetchContext();
    InsertContext defaultInsertContext = client.getInsertContext(false);
    int maxMemoryLimitedJobThreads = Runtime.getRuntime().availableProcessors() / 2; // Some disk I/O ... tunable REDFLAG
    maxMemoryLimitedJobThreads = Math.min(maxMemoryLimitedJobThreads, node.nodeStats.getThreadLimit()/20);
    maxMemoryLimitedJobThreads = Math.max(1, maxMemoryLimitedJobThreads);
        // FIXME review thread limits. This isn't just memory, it's CPU and disk as well, so we don't want it too big??
        // FIXME l10n the errors?
    nodeConfig.register("memoryLimitedJobThreadLimit", maxMemoryLimitedJobThreads, sortOrder++, true, false,
            "NodeClientCore.memoryLimitedJobThreadLimit", "NodeClientCore.memoryLimitedJobThreadLimitLong", new IntCallback() {

                    @Override
                    public Integer get() {
                        return memoryLimitedJobRunner.getMaxThreads();
                    }

                    @Override
                    public void set(Integer val) throws InvalidConfigValueException,
                            NodeNeedRestartException {
                        if(val < 1) throw new InvalidConfigValueException(l10n("memoryLimitedJobThreadLimitMustBe1Plus"));
                        memoryLimitedJobRunner.setMaxThreads(val);
                    }
       
    }, false);
    long defaultMemoryLimitedJobMemoryLimit = FECCodec.MIN_MEMORY_ALLOCATION;
    long overallMemoryLimit = NodeStarter.getMemoryLimitBytes();
    if(overallMemoryLimit > 512*1024*1024) {
        // FIXME review default memory limits
        defaultMemoryLimitedJobMemoryLimit += (overallMemoryLimit - 512*1024*1024) / 20;
    }
    nodeConfig.register("memoryLimitedJobMemoryLimit", defaultMemoryLimitedJobMemoryLimit, sortOrder++, true, false,
            "NodeClientCore.memoryLimitedJobMemoryLimit", "NodeClientCore.memoryLimitedJobMemoryLimitLong", new LongCallback() {

                    @Override
                    public Long get() {
                        return memoryLimitedJobRunner.getCapacity();
                    }
View Full Code Here

            persistentDiskChecker.setMinDiskSpace(size);
        }
    }

    private void initDiskSpaceLimits(SubConfig nodeConfig, int sortOrder) {
        nodeConfig.register("minDiskFreeLongTerm", "1G", sortOrder++, true, true, "NodeClientCore.minDiskFreeLongTerm", "NodeClientCore.minDiskFreeLongTermLong", new LongCallback() {

            @Override
            public Long get() {
                synchronized(NodeClientCore.this) {
                    return minDiskFreeLongTerm;
                }
            }

            @Override
            public void set(Long val) throws InvalidConfigValueException, NodeNeedRestartException {
                synchronized(NodeClientCore.this) {
                    if(val < 0) throw new InvalidConfigValueException(l10n("minDiskFreeMustBePositive"));
                    minDiskFreeLongTerm = val;
                }
                updatePersistentRAFSpaceLimit();
            }
           
        }, true);
        minDiskFreeLongTerm = nodeConfig.getLong("minDiskFreeLongTerm");
       
        nodeConfig.register("minDiskFreeShortTerm", "512M", sortOrder++, true, true, "NodeClientCore.minDiskFreeShortTerm", "NodeClientCore.minDiskFreeShortTermLong", new LongCallback() {

            @Override
            public Long get() {
                synchronized(NodeClientCore.this) {
                    return minDiskFreeShortTerm;
View Full Code Here

   
    // max space used by zipped logs
     
    config.register("maxZippedLogsSize", "10M", 3, true, true, "LogConfigHandler.maxZippedLogsSize",
        "LogConfigHandler.maxZippedLogsSizeLong",
        new LongCallback() {
          @Override
          public Long get() {
            return maxZippedLogsSize;
          }
          @Override
          public void set(Long val) throws InvalidConfigValueException {
            if (val < 0)
                  val = 0L;
            maxZippedLogsSize = val;
            if (fileLoggerHook != null) {
              fileLoggerHook.setMaxOldLogsSize(val);
            }
          }
        }, true);
     
    maxZippedLogsSize = config.getLong("maxZippedLogsSize");
     
    // These two are forced below so we don't need to check them now
     
    // priority
     
    // Node must override this to minor on testnet.
    config.register("priority", "warning", 4, false, false, "LogConfigHandler.minLoggingPriority",
        "LogConfigHandler.minLoggingPriorityLong",
        new PriorityCallback());
     
    // detailed priority
     
    config.register("priorityDetail", "", 5, true, false, "LogConfigHandler.detaildPriorityThreshold",
        "LogConfigHandler.detaildPriorityThresholdLong",
        new StringCallback() {
          @Override
          public String get() {
            LoggerHookChain chain = Logger.getChain();
            return chain.getDetailedThresholds();
          }

          @Override
          public void set(String val) throws InvalidConfigValueException {
            LoggerHookChain chain = Logger.getChain();
            try {
              chain.setDetailedThresholds(val);
            } catch (InvalidThresholdException e) {
              throw new InvalidConfigValueException(e.getMessage());
            }
          }
        });
     
    // interval
     
    config.register("interval", "1HOUR", 5, true, false, "LogConfigHandler.rotationInterval",
        "LogConfigHandler.rotationIntervalLong",
        new StringCallback() {
          @Override
          public String get() {
            return logRotateInterval;
          }

          @Override
          public void set(String val) throws InvalidConfigValueException {
            if (val.equals(logRotateInterval)) return;
            if (fileLoggerHook != null) {
              try {
                fileLoggerHook.setInterval(val);
              } catch (FileLoggerHook.IntervalParseException e) {
                throw new OptionFormatException(e.getMessage());
              }
            }
            logRotateInterval = val;
          }
        });
     
    logRotateInterval = config.getString("interval");
     
    // max cached bytes in RAM
    config.register("maxCachedBytes", "1M", 6, true, false, "LogConfigHandler.maxCachedBytes",
        "LogConfigHandler.maxCachedBytesLong",
        new LongCallback() {
          @Override
          public Long get() {
            return maxCachedLogBytes;
          }
          @Override
          public void set(Long val) throws InvalidConfigValueException {
            if (val < 0) val = 0L;
            if (val == maxCachedLogBytes) return;
            maxCachedLogBytes = val;
            if (fileLoggerHook != null) fileLoggerHook.setMaxListBytes(val);
          }
        }, true);
     
    maxCachedLogBytes = config.getLong("maxCachedBytes");
     
    // max cached lines in RAM
    config.register("maxCachedLines", "10k", 7, true, false, "LogConfigHandler.maxCachedLines",
        "LogConfigHandler.maxCachedLinesLong",
        new IntCallback() {
          @Override
          public Integer get() {
            return maxCachedLogLines;
          }
          @Override
          public void set(Integer val) throws InvalidConfigValueException, NodeNeedRestartException {
            if(val < 0) val = 0;
            if(val == maxCachedLogLines) return;
            maxCachedLogLines = val;
            throw new NodeNeedRestartException("logger.maxCachedLogLines");
          }
        }, false);
     
    maxCachedLogLines = config.getInt("maxCachedLines");
   
    config.register("maxBacklogNotBusy", "60000", 8, true, false, "LogConfigHandler.maxBacklogNotBusy",
        "LogConfigHandler.maxBacklogNotBusy",
        new LongCallback() {

          @Override
          public Long get() {
            return maxBacklogNotBusy;
          }
View Full Code Here

        }
      }
    });
    ignoreLocalVsRemoteBandwidthLiability = statsConfig.getBoolean("ignoreLocalVsRemoteBandwidthLiability");

    statsConfig.register("maxPingTime", DEFAULT_MAX_PING_TIME, sortOrder++, true, true, "NodeStat.maxPingTime", "NodeStat.maxPingTimeLong", new LongCallback() {

      @Override
      public Long get() {
        return maxPingTime;
      }

      @Override
      public void set(Long val) throws InvalidConfigValueException, NodeNeedRestartException {
        maxPingTime = val;
      }

    }, false);
    maxPingTime = statsConfig.getLong("maxPingTime");

    statsConfig.register("subMaxPingTime", DEFAULT_SUB_MAX_PING_TIME, sortOrder++, true, true, "NodeStat.subMaxPingTime", "NodeStat.subMaxPingTimeLong", new LongCallback() {

      @Override
      public Long get() {
        return subMaxPingTime;
      }
View Full Code Here

    /*
     * Very small initial store size, since the node will preallocate it when starting up for the first time,
     * BLOCKING STARTUP, and since everyone goes through the wizard anyway...
     */
    nodeConfig.register("storeSize", DEFAULT_STORE_SIZE, sortOrder++, false, true, "Node.storeSize", "Node.storeSizeLong",
        new LongCallback() {

          @Override
          public Long get() {
            return maxTotalDatastoreSize;
          }

          @Override
          public void set(Long storeSize) throws InvalidConfigValueException {
            if(storeSize < MIN_STORE_SIZE)
              throw new InvalidConfigValueException(l10n("invalidStoreSize"));
            long newMaxStoreKeys = storeSize / sizePerKey;
            if(newMaxStoreKeys == maxTotalKeys) return;
            // Update each datastore
            synchronized(Node.this) {
              maxTotalDatastoreSize = storeSize;
              maxTotalKeys = newMaxStoreKeys;
              maxStoreKeys = maxTotalKeys / 2;
              maxCacheKeys = maxTotalKeys - maxStoreKeys;
            }
            try {
              chkDatastore.setMaxKeys(maxStoreKeys, storeForceBigShrinks);
              chkDatacache.setMaxKeys(maxCacheKeys, storeForceBigShrinks);
              pubKeyDatastore.setMaxKeys(maxStoreKeys, storeForceBigShrinks);
              pubKeyDatacache.setMaxKeys(maxCacheKeys, storeForceBigShrinks);
              sskDatastore.setMaxKeys(maxStoreKeys, storeForceBigShrinks);
              sskDatacache.setMaxKeys(maxCacheKeys, storeForceBigShrinks);
            } catch (IOException e) {
              // FIXME we need to be able to tell the user.
              Logger.error(this, "Caught "+e+" resizing the datastore", e);
              System.err.println("Caught "+e+" resizing the datastore");
              e.printStackTrace();
            }
            //Perhaps a bit hackish...? Seems like this should be near it's definition in NodeStats.
            nodeStats.avgStoreCHKLocation.changeMaxReports((int)maxStoreKeys);
            nodeStats.avgCacheCHKLocation.changeMaxReports((int)maxCacheKeys);
            nodeStats.avgSlashdotCacheCHKLocation.changeMaxReports((int)maxCacheKeys);
            nodeStats.avgClientCacheCHKLocation.changeMaxReports((int)maxCacheKeys);

            nodeStats.avgStoreSSKLocation.changeMaxReports((int)maxStoreKeys);
            nodeStats.avgCacheSSKLocation.changeMaxReports((int)maxCacheKeys);
            nodeStats.avgSlashdotCacheSSKLocation.changeMaxReports((int)maxCacheKeys);
            nodeStats.avgClientCacheSSKLocation.changeMaxReports((int)maxCacheKeys);
          }
    }, true);

    maxTotalDatastoreSize = nodeConfig.getLong("storeSize");

    if(maxTotalDatastoreSize < MIN_STORE_SIZE && !storeType.equals("ram")) { // totally arbitrary minimum!
      throw new NodeInitException(NodeInitException.EXIT_INVALID_STORE_SIZE, "Store size too small");
    }

    maxTotalKeys = maxTotalDatastoreSize / sizePerKey;
   
    nodeConfig.register("storeUseSlotFilters", true, sortOrder++, true, false, "Node.storeUseSlotFilters", "Node.storeUseSlotFiltersLong", new BooleanCallback() {

      public Boolean get() {
        synchronized(Node.this) {
          return storeUseSlotFilters;
        }
      }

      public void set(Boolean val) throws InvalidConfigValueException,
          NodeNeedRestartException {
        synchronized(Node.this) {
          storeUseSlotFilters = val;
        }
       
        // FIXME l10n
        throw new NodeNeedRestartException("Need to restart to change storeUseSlotFilters");
      }
     
    });
   
    storeUseSlotFilters = nodeConfig.getBoolean("storeUseSlotFilters");
   
    nodeConfig.register("storeSaltHashSlotFilterPersistenceTime", ResizablePersistentIntBuffer.DEFAULT_PERSISTENCE_TIME, sortOrder++, true, false,
        "Node.storeSaltHashSlotFilterPersistenceTime", "Node.storeSaltHashSlotFilterPersistenceTimeLong", new IntCallback() {

          @Override
          public Integer get() {
            return ResizablePersistentIntBuffer.getPersistenceTime();
          }

          @Override
          public void set(Integer val)
              throws InvalidConfigValueException,
              NodeNeedRestartException {
            if(val >= -1)
              ResizablePersistentIntBuffer.setPersistenceTime(val);
            else
              throw new InvalidConfigValueException(l10n("slotFilterPersistenceTimeError"));
          }
     
    }, false);

    nodeConfig.register("storeSaltHashResizeOnStart", false, sortOrder++, true, false,
        "Node.storeSaltHashResizeOnStart", "Node.storeSaltHashResizeOnStartLong", new BooleanCallback() {
      @Override
      public Boolean get() {
        return storeSaltHashResizeOnStart;
      }

      @Override
      public void set(Boolean val) throws InvalidConfigValueException, NodeNeedRestartException {
        storeSaltHashResizeOnStart = val;
      }
    });
    storeSaltHashResizeOnStart = nodeConfig.getBoolean("storeSaltHashResizeOnStart");

    this.storeDir = setupProgramDir(installConfig, "storeDir", userDir().file("datastore").getPath(), "Node.storeDirectory", "Node.storeDirectoryLong", nodeConfig);
    installConfig.finishedInitialization();

    final String suffix = getStoreSuffix();

    maxStoreKeys = maxTotalKeys / 2;
    maxCacheKeys = maxTotalKeys - maxStoreKeys;

    /*
     * On Windows, setting the file length normally involves writing lots of zeros.
     * So it's an uninterruptible system call that takes a loooong time. On OS/X,
     * presumably the same is true. If the RNG is fast enough, this means that
     * setting the length and writing random data take exactly the same amount
     * of time. On most versions of Unix, holes can be created. However on all
     * systems, predictable disk usage is a good thing. So lets turn it on by
     * default for now, on all systems. The datastore can be read but mostly not
     * written while the random data is being written.
     */
    nodeConfig.register("storePreallocate", true, sortOrder++, true, true, "Node.storePreallocate", "Node.storePreallocateLong",
        new BooleanCallback() {
          @Override
                    public Boolean get() {
                      return storePreallocate;
                    }

          @Override
                    public void set(Boolean val) throws InvalidConfigValueException, NodeNeedRestartException {
            storePreallocate = val;
            if (storeType.equals("salt-hash")) {
              setPreallocate(chkDatastore, val);
              setPreallocate(chkDatacache, val);
              setPreallocate(pubKeyDatastore, val);
              setPreallocate(pubKeyDatacache, val);
              setPreallocate(sskDatastore, val);
              setPreallocate(sskDatacache, val);
            }
                    }

          private void setPreallocate(StoreCallback<?> datastore,
              boolean val) {
            // Avoid race conditions by checking first.
            FreenetStore<?> store = datastore.getStore();
            if(store instanceof SaltedHashFreenetStore)
              ((SaltedHashFreenetStore<?>)store).setPreallocate(val);
          }}
    );
    storePreallocate = nodeConfig.getBoolean("storePreallocate");

    if(File.separatorChar == '/' && System.getProperty("os.name").toLowerCase().indexOf("mac os") < 0) {
      securityLevels.addPhysicalThreatLevelListener(new SecurityLevelListener<SecurityLevels.PHYSICAL_THREAT_LEVEL>() {

        @Override
        public void onChange(PHYSICAL_THREAT_LEVEL oldLevel, PHYSICAL_THREAT_LEVEL newLevel) {
          try {
            if(newLevel == PHYSICAL_THREAT_LEVEL.LOW)
              nodeConfig.set("storePreallocate", false);
            else
              nodeConfig.set("storePreallocate", true);
          } catch (NodeNeedRestartException e) {
            // Ignore
          } catch (InvalidConfigValueException e) {
            // Ignore
          }
        }
      });
    }

    securityLevels.addPhysicalThreatLevelListener(new SecurityLevelListener<SecurityLevels.PHYSICAL_THREAT_LEVEL>() {

      @Override
      public void onChange(PHYSICAL_THREAT_LEVEL oldLevel, PHYSICAL_THREAT_LEVEL newLevel) {
          if(newLevel == PHYSICAL_THREAT_LEVEL.MAXIMUM) {
            synchronized(this) {
              clientCacheAwaitingPassword = false;
              databaseAwaitingPassword = false;
            }
            try {
                            killMasterKeysFile();
                clientCore.clientLayerPersister.disableWrite();
                clientCore.clientLayerPersister.waitForNotWriting();
                            clientCore.clientLayerPersister.deleteAllFiles();
            } catch (IOException e) {
              masterKeysFile.delete();
              Logger.error(this, "Unable to securely delete "+masterKeysFile);
              System.err.println(NodeL10n.getBase().getString("SecurityLevels.cantDeletePasswordFile", "filename", masterKeysFile.getAbsolutePath()));
              clientCore.alerts.register(new SimpleUserAlert(true, NodeL10n.getBase().getString("SecurityLevels.cantDeletePasswordFileTitle"), NodeL10n.getBase().getString("SecurityLevels.cantDeletePasswordFile"), NodeL10n.getBase().getString("SecurityLevels.cantDeletePasswordFileTitle"), UserAlert.CRITICAL_ERROR));
            }
          }
          if(oldLevel == PHYSICAL_THREAT_LEVEL.MAXIMUM && newLevel != PHYSICAL_THREAT_LEVEL.HIGH) {
              // Not passworded.
              // Create the master.keys.
              // Keys must exist.
              try {
                  MasterKeys keys;
                  synchronized(this) {
                      keys = Node.this.keys;
                  }
                            keys.changePassword(masterKeysFile, "", secureRandom);
                        } catch (IOException e) {
                            Logger.error(this, "Unable to create encryption keys file: "+masterKeysFile+" : "+e, e);
                            System.err.println("Unable to create encryption keys file: "+masterKeysFile+" : "+e);
                            e.printStackTrace();
                        }
          }
        }

      });

    if(securityLevels.physicalThreatLevel == PHYSICAL_THREAT_LEVEL.MAXIMUM) {
      try {
        killMasterKeysFile();
      } catch (IOException e) {
        String msg = "Unable to securely delete old master.keys file when switching to MAXIMUM seclevel!!";
        System.err.println(msg);
        throw new NodeInitException(NodeInitException.EXIT_CANT_WRITE_MASTER_KEYS, msg);
      }
    }
   
    long defaultCacheSize;
    long memoryLimit = NodeStarter.getMemoryLimitBytes();
    // This is tricky because systems with low memory probably also have slow disks, but using
    // up too much memory can be catastrophic...
    // Total alchemy, FIXME!
    if(memoryLimit == Long.MAX_VALUE || memoryLimit < 0)
      defaultCacheSize = 1024*1024;
    else if(memoryLimit <= 128*1024*1024)
      defaultCacheSize = 0; // Turn off completely for very small memory.
    else {
      // 9 stores, total should be 5% of memory, up to maximum of 1MB per store at 308MB+
      defaultCacheSize = Math.min(1024*1024, (memoryLimit - 128*1024*1024) / (20*9));
    }
   
    nodeConfig.register("cachingFreenetStoreMaxSize", defaultCacheSize, sortOrder++, true, false, "Node.cachingFreenetStoreMaxSize", "Node.cachingFreenetStoreMaxSizeLong",
      new LongCallback() {
        @Override
        public Long get() {
          synchronized(Node.this) {
            return cachingFreenetStoreMaxSize;
          }
        }

        @Override
        public void set(Long val) throws InvalidConfigValueException, NodeNeedRestartException {
          if(val < 0) throw new InvalidConfigValueException(l10n("invalidMemoryCacheSize"));
          // Any positive value is legal. In particular, e.g. 1200 bytes would cause us to cache SSKs but not CHKs.
          synchronized(Node.this) {
            cachingFreenetStoreMaxSize = val;
          }
          throw new NodeNeedRestartException("Caching Maximum Size cannot be changed on the fly");
        }
    }, true);
   
    cachingFreenetStoreMaxSize = nodeConfig.getLong("cachingFreenetStoreMaxSize");
    if(cachingFreenetStoreMaxSize < 0)
      throw new NodeInitException(NodeInitException.EXIT_BAD_CONFIG, l10n("invalidMemoryCacheSize"));
   
    nodeConfig.register("cachingFreenetStorePeriod", "300k", sortOrder++, true, false, "Node.cachingFreenetStorePeriod", "Node.cachingFreenetStorePeriod",
      new LongCallback() {
        @Override
        public Long get() {
          synchronized(Node.this) {
            return cachingFreenetStorePeriod;
          }
        }

        @Override
        public void set(Long val) throws InvalidConfigValueException, NodeNeedRestartException {
          synchronized(Node.this) {
            cachingFreenetStorePeriod = val;
          }
          throw new NodeNeedRestartException("Caching Period cannot be changed on the fly");
        }
    }, true);
   
    cachingFreenetStorePeriod = nodeConfig.getLong("cachingFreenetStorePeriod");

    boolean shouldWriteConfig = false;

    if(storeType.equals("bdb-index")) {
      System.err.println("Old format Berkeley DB datastore detected.");
      System.err.println("This datastore format is no longer supported.");
      System.err.println("The old datastore will be securely deleted.");
      storeType = "salt-hash";
      shouldWriteConfig = true;
      deleteOldBDBIndexStoreFiles();
    }
    if (storeType.equals("salt-hash")) {
      initRAMFS();
      // FIXME remove migration code
      final int lastVersionWithBloom = 1384;
      if(lastVersion > 0 && lastVersion <= lastVersionWithBloom) {
        // Check for a comment in wrapper.conf saying we've already upgraded, otherwise update it and restart.
        long extraMemory = maxTotalKeys * 3 * 4;
        int extraMemoryMB = (int)Math.min(Integer.MAX_VALUE, ((extraMemory + 1024 * 1024 - 1) / (1024 * 1024)));
        if(extraMemoryMB >= 10) {
          System.out.println("Need "+extraMemoryMB+"MB extra space in heap for slot filters.");
          UpdateDeployContext.CHANGED changed =
            UpdateDeployContext.tryIncreaseMemoryLimit(extraMemoryMB, " Increased because of slot filters in "+(lastVersionWithBloom+1));
          if(changed == CHANGED.SUCCESS) {
            WrapperManager.restart();
            System.err.println("Unable to restart after increasing memory limit for the slot filters (the total memory usage is decreased relative to bloom filters but the heap size needs to grow). Probably due to not running in the wrapper.");
            System.err.println("If the node crashes due to out of memory, be it on your own head!");
            System.err.println("You need to increase wrapper.java.maxmemory by "+extraMemoryMB);
          } else if(changed == CHANGED.FAIL) {
            System.err.println("Unable to increase the memory limit for the slot filters (the total memory usage is decreased relative to bloom filters but the heap size needs to grow). Most likely due to being unable to write wrapper.conf or similar problem.");
            System.err.println("If the node crashes due to out of memory, be it on your own head!");
            System.err.println("You need to increase wrapper.java.maxmemory by "+extraMemoryMB);
          } else /*if(changed == CHANGED.ALREADY)*/ {
            System.err.println("Memory limit has already been increased for slot filters, continuing startup.");
          }
        }
      }
      initSaltHashFS(suffix, false, null);
    } else {
      initRAMFS();
    }

    if(databaseAwaitingPassword) createPasswordUserAlert();

    // Client cache

    // Default is 10MB, in memory only. The wizard will change this.

    nodeConfig.register("clientCacheType", "ram", sortOrder++, true, true, "Node.clientCacheType", "Node.clientCacheTypeLong", new ClientCacheTypeCallback());

    clientCacheType = nodeConfig.getString("clientCacheType");

    nodeConfig.register("clientCacheSize", DEFAULT_CLIENT_CACHE_SIZE, sortOrder++, false, true, "Node.clientCacheSize", "Node.clientCacheSizeLong",
        new LongCallback() {

          @Override
          public Long get() {
            return maxTotalClientCacheSize;
          }

          @Override
          public void set(Long storeSize) throws InvalidConfigValueException {
            if(storeSize < MIN_CLIENT_CACHE_SIZE)
              throw new InvalidConfigValueException(l10n("invalidStoreSize"));
            long newMaxStoreKeys = storeSize / sizePerKey;
            if(newMaxStoreKeys == maxClientCacheKeys) return;
            // Update each datastore
            synchronized(Node.this) {
              maxTotalClientCacheSize = storeSize;
              maxClientCacheKeys = newMaxStoreKeys;
            }
            try {
              chkClientcache.setMaxKeys(maxClientCacheKeys, storeForceBigShrinks);
              pubKeyClientcache.setMaxKeys(maxClientCacheKeys, storeForceBigShrinks);
              sskClientcache.setMaxKeys(maxClientCacheKeys, storeForceBigShrinks);
            } catch (IOException e) {
              // FIXME we need to be able to tell the user.
              Logger.error(this, "Caught "+e+" resizing the clientcache", e);
              System.err.println("Caught "+e+" resizing the clientcache");
              e.printStackTrace();
            }
          }
    }, true);

    maxTotalClientCacheSize = nodeConfig.getLong("clientCacheSize");

    if(maxTotalClientCacheSize < MIN_CLIENT_CACHE_SIZE) {
      throw new NodeInitException(NodeInitException.EXIT_INVALID_STORE_SIZE, "Client cache size too small");
    }

    maxClientCacheKeys = maxTotalClientCacheSize / sizePerKey;

    boolean startedClientCache = false;

    if (clientCacheType.equals("salt-hash")) {
        if(clientCacheKey == null) {
            System.err.println("Cannot open client-cache, it is passworded");
            setClientCacheAwaitingPassword();
        } else {
            initSaltHashClientCacheFS(suffix, false, clientCacheKey);
            startedClientCache = true;
        }
    } else if(clientCacheType.equals("none")) {
      initNoClientCacheFS();
      startedClientCache = true;
    } else { // ram
      initRAMClientCacheFS();
      startedClientCache = true;
    }
    if(!startedClientCache)
      initRAMClientCacheFS();
   
    if(!clientCore.loadedDatabase() && databaseKey != null)  {
      try {
        lateSetupDatabase(databaseKey);
      } catch (MasterKeysWrongPasswordException e2) {
        System.err.println("Impossible: "+e2);
        e2.printStackTrace();
      } catch (MasterKeysFileSizeException e2) {
        System.err.println("Impossible: "+e2);
        e2.printStackTrace();
      } catch (IOException e2) {
        System.err.println("Unable to load database: "+e2);
        e2.printStackTrace();
      }
    }

    nodeConfig.register("useSlashdotCache", true, sortOrder++, true, false, "Node.useSlashdotCache", "Node.useSlashdotCacheLong", new BooleanCallback() {

      @Override
      public Boolean get() {
        return useSlashdotCache;
      }

      @Override
      public void set(Boolean val) throws InvalidConfigValueException, NodeNeedRestartException {
        useSlashdotCache = val;
      }

    });
    useSlashdotCache = nodeConfig.getBoolean("useSlashdotCache");

    nodeConfig.register("writeLocalToDatastore", false, sortOrder++, true, false, "Node.writeLocalToDatastore", "Node.writeLocalToDatastoreLong", new BooleanCallback() {

      @Override
      public Boolean get() {
        return writeLocalToDatastore;
      }

      @Override
      public void set(Boolean val) throws InvalidConfigValueException, NodeNeedRestartException {
        writeLocalToDatastore = val;
      }

    });

    writeLocalToDatastore = nodeConfig.getBoolean("writeLocalToDatastore");

    // LOW network *and* physical seclevel = writeLocalToDatastore

    securityLevels.addNetworkThreatLevelListener(new SecurityLevelListener<NETWORK_THREAT_LEVEL>() {

      @Override
      public void onChange(NETWORK_THREAT_LEVEL oldLevel, NETWORK_THREAT_LEVEL newLevel) {
        if(newLevel == NETWORK_THREAT_LEVEL.LOW && securityLevels.getPhysicalThreatLevel() == PHYSICAL_THREAT_LEVEL.LOW)
          writeLocalToDatastore = true;
        else
          writeLocalToDatastore = false;
      }

    });

    securityLevels.addPhysicalThreatLevelListener(new SecurityLevelListener<PHYSICAL_THREAT_LEVEL>() {

      @Override
      public void onChange(PHYSICAL_THREAT_LEVEL oldLevel, PHYSICAL_THREAT_LEVEL newLevel) {
        if(newLevel == PHYSICAL_THREAT_LEVEL.LOW && securityLevels.getNetworkThreatLevel() == NETWORK_THREAT_LEVEL.LOW)
          writeLocalToDatastore = true;
        else
          writeLocalToDatastore = false;
      }

    });

    nodeConfig.register("slashdotCacheLifetime", MINUTES.toMillis(30), sortOrder++, true, false, "Node.slashdotCacheLifetime", "Node.slashdotCacheLifetimeLong", new LongCallback() {

      @Override
      public Long get() {
        return chkSlashdotcacheStore.getLifetime();
      }

      @Override
      public void set(Long val) throws InvalidConfigValueException, NodeNeedRestartException {
        if(val < 0) throw new InvalidConfigValueException("Must be positive!");
        chkSlashdotcacheStore.setLifetime(val);
        pubKeySlashdotcacheStore.setLifetime(val);
        sskSlashdotcacheStore.setLifetime(val);
      }

    }, false);

    long slashdotCacheLifetime = nodeConfig.getLong("slashdotCacheLifetime");

    nodeConfig.register("slashdotCacheSize", DEFAULT_SLASHDOT_CACHE_SIZE, sortOrder++, false, true, "Node.slashdotCacheSize", "Node.slashdotCacheSizeLong",
        new LongCallback() {

          @Override
          public Long get() {
            return maxSlashdotCacheSize;
          }
View Full Code Here

TOP

Related Classes of freenet.support.api.LongCallback

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.