Code to get TPS of a server

Discussion in 'Plugin Development' started by Techtony96, Aug 29, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Techtony96

    I know that there isn't a bukkit import (no idea what to call it) and you have to do it by hand.

    Could someone write the code for me to get the TPS of a server?

    btw: There is 2o ticks per second on a non laggy server

    i have some code now, but it always is 0, and i know for a fact that the TPS of the server is NOT 0

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
  2. Offline

    KeybordPiano459

    And the code is...
     
  3. You could take a look at the source of the awesome plugin LagMeter, which does that (in addition to displaying RAM usage).

    In theory, what it probably does in some variant:
    - have a synchronous task executing every tick counting up a number by 1
    - have an aysynchronous task executing every second (only a delayed task running an infinite while-loop checking the system time); when that task runs, the number will contain the amount of ticks done in the last second --> your TPS.
    Then the number is reset.

    Make sure everything is synchronized properly and you put your async task to sleep and stuff ;)

    A simpler way that avoids threading, if you only need the information "onCommand", and not at any given point of time:

    - when the command is done, launch your task that runs each tick (this is your "benchmark")
    - store the current time
    - the task repeats until the counter reached x ticks (I'd choose more than 20 to increase accuracy, maybe 100 or something)
    - take the time now after the ticks have been reached, subtract from the starting time, do some math magic.
    - the formula should be something like that I believe:
    Code:
    double ticksPerSecond = 1000.0 / ((endTime - startTime) / passedTicks);
    (assuming endTime and startTime are in milliseconds, passedTicks are the amount of ticks your benchmark lasted)
     
  4. Offline

    Techtony96

    http://forums.bukkit.org/threads/explain-this-code.95482

    That is the original form

    I have no idea what all these threads tasks, sync tasks async tasks, etc. mean. This is probably my real first plugin, so im still working on the bukkit API and Java

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
  5. Offline

    Sagacious_Zed Bukkit Docs

    There is lots to learn in this area, I suppose this is as good a starting point as anything else.
     
  6. All about the bukkit scheduler: http://wiki.bukkit.org/Scheduler_Programming
    If you take my second suggestion (onCommand --> do something), you don't need the "asynchronous" part, though. If you're a beginner, I would really advice NOT to try to get into threading/asynchronous tasks to begin with.
    It's really complicated and needs a good foundation to actually understand it.

    If you go a bit into how the scheduler works (link above), what a repeating task is and stuff, it should be possible.

    Keywords you're going to need:
    onCommand
    scheduleSyncRepeatingTask
    cancelTask
    System.currentTimeMillis()
     
  7. I guess you forgot about your previous thread... where I actually gave you a working code
    http://forums.bukkit.org/threads/how-to-find-tps-of-a-server.94671/

    EDIT:
    Oh wow then you posted another thread to ask what my code means ? =) Why didn't you post in that same thread :confused:
    And that code works, I've tested it before posting :)
    Look, just ran it again:
    console log (open)
    Code:
    02:52:18 [INFO] TPS = 17
    02:52:19 [INFO] TPS = 17
    02:52:20 [INFO] TPS = 18
    02:52:21 [INFO] TPS = 18
    02:52:22 [INFO] TPS = 18
    02:52:23 [INFO] TPS = 19
    02:52:24 [INFO] TPS = 19
    02:52:25 [INFO] TPS = 19
    02:52:26 [INFO] TPS = 18
    02:52:27 [INFO] TPS = 19
    02:52:28 [INFO] TPS = 19
    02:52:29 [INFO] TPS = 18
    02:52:30 [INFO] TPS = 19
    02:52:31 [INFO] TPS = 19
    02:52:32 [INFO] TPS = 18
    02:52:33 [INFO] TPS = 18
    02:52:34 [INFO] TPS = 19
    02:52:35 [INFO] TPS = 19
    02:52:36 [INFO] TPS = 18
    02:52:37 [INFO] TPS = 19
    02:52:38 [INFO] TPS = 19
    02:52:39 [INFO] TPS = 18
    02:52:46 [INFO] TPS = 20
    02:52:47 [INFO] TPS = 19
    02:52:48 [INFO] TPS = 19
    02:52:49 [INFO] TPS = 19
    02:52:50 [INFO] TPS = 18
    02:52:51 [INFO] TPS = 19
    02:52:52 [INFO] TPS = 19
    02:52:53 [INFO] TPS = 18
    02:52:54 [INFO] TPS = 19

    Works fine.

    You'll never get proper experience like this if you keep "resetting" threads by making new ones.
     
  8. Offline

    Techtony96

    think you could write that for me? i need it for my server.
     
  9. If you really want to learn, stick around and learn.

    But if you only need it for your server, stop wasting our time and say you want the end result and post in the Plugin Requests section.


    EDIT:
    Also, I reviewed that other thread where you asked about my code... you changed the delay of the task.
    Code:
    }}, 60L, 60L/*6000L*/);
    That's 60 ticks, 3 seconds... you can't get ticks per second if you add a tick each 3 seconds, no wonder it was only printing 0. So change it back to 1.
     
  10. Offline

    Techtony96

    i must have messed something up, because it is returning 0 now. What my main goal of the plugin is is for this to run every 5 mins, to check the TPS, and if the TPS is below 15, to run some console commands. I think i have a your TPS calculator in another loop, which runs every 5 mins. Also, the reason i posted the 2nd topic is because i couldnt find my original post with your code in it. Then i posted this one, because people kept telling me what was wrong with it, which i tried to fix, but was a 1st grader taking algebra. Had no idea what was going on, other than the few wikis bukkit has.

    I will prob start posting in the plugin requests section, as i learn the best with examples. Thanks for the help Digi. Will try your original code tomorrow.
     
  11. My code is not a TPS calculator, it's more of a TPS monitor, it needs to run each tick to properly work :}
    And I found it pretty fast by searching for "TPS" only in titles in the Plugin development section.

    To avoid having 2 tasks, here's a slightly changed version of that other code I posted to trigger a message each 5 minutes (as example):
    Code:
    // fields
    private int tps = 0;
    
    // in onEnable or something
    getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable()
    {
    	long sec;
    	long currentSec;
    	int ticks;
    	int delay;
    	
    	@Override
    	public void run()
    	{
    		sec = (System.currentTimeMillis() / 1000);
    		
    		if(currentSec == sec)
    		{
    			// this code block triggers each tick
    			
    			ticks++;
    		}
    		else
    		{
    			// this code block triggers each second
    			
    			currentSec = sec;
    			tps = (tps == 0 ? ticks : ((tps + ticks) / 2));
    			ticks = 0;
    			
    			if((++delay % 300) == 0)
    			{
    				// this code block triggers each 5 minutes
    				
    				delay = 0;
    				
    				Bukkit.broadcastMessage("Server current TPS = " + tps);
    			}
    		}
    	}
    }, 0, 1); // do not change the "1" value, the other one is just initial delay, I recommend 0 = start instantly.
    EDIT:
    I also recommend you do this in your onDisable():
    Code:
    getServer().getScheduler().cancelTasks(this);
    Do not use cancelAllTasks() because that cancels tasks for other plugins as well.
     
  12. Offline

    flyingtacoz

    Very cool, how can you make this a command?
     
  13. You just print the "tps" value :)
    It needs to run a few seconds to properly determine the ticks per second, it's easier to just let it run continously because it's *very* fast, doesn't affect perfornace at all.

    But you could start it when you use the command and make it stop and print the result after 3 seconds or so.... like:

    Code:
    private taskId = -1; // field
    
    // in your command
    // also set your "sender" as final so you can use it inside the task
    
    if(taskId >= 0)
    {
        sender.sendMessage("The TPS is stil beeing monitored, please wait...");
        return true;
    }
    
    taskId = getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable()
    // ...
    // replace the 5-minute code block with:
    
    if(++delay > 3)
    {
        sender.sendMessage("TPS of the last 3 seconds is " + tps);
        getServer().getScheduler().cancelTask(taskId);
        taskId = -1;
    }
     
  14. Offline

    Techtony96

    I am using the code from this post /\ and here is my entire code:

    Code:java
    1.  
    2. package me.Techtony96.LagFix;
    3.  
    4. import org.bukkit.Bukkit;
    5. import org.bukkit.event.Listener;
    6. import org.bukkit.plugin.java.JavaPlugin;
    7.  
    8. public class LagFix extends JavaPlugin implements Listener{
    9. private int tps = 0;
    10.  
    11. @Override
    12. public void onDisable(){
    13. getServer().getScheduler().cancelTasks(this);
    14. }
    15.  
    16. @Override
    17. public void onEnable(){
    18. getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable()
    19. {
    20. long sec;
    21. long currentSec;
    22. int ticks;
    23. int delay;
    24.  
    25. @Override
    26. public void run()
    27. {
    28. sec = (System.currentTimeMillis() / 1000);
    29.  
    30. if(currentSec == sec)
    31. {
    32. // this code block triggers each tick
    33.  
    34. ticks++;
    35. }
    36. else
    37. {
    38. // this code block triggers each second
    39.  
    40. currentSec = sec;
    41. tps = (tps == 0 ? ticks : ((tps + ticks) / 2));
    42. ticks = 0;
    43.  
    44. if((++delay % 300) == 0)
    45. {
    46. // this code block triggers each 5 minutes
    47.  
    48. delay = 0;
    49.  
    50. Bukkit.broadcastMessage("Server current TPS = " + tps);
    51. }
    52. }
    53. }
    54. }, 0, 1); // do not change the "1" value, the other one is just initial delay, I recommend 0 = start instantly.
    55.  
    56.  
    57.  
    58.  
    59.  
    60. if (tps <= 15){
    61. Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "butcher");
    62. Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "say Lag Fixed :D");
    63. }
    64. else if (tps > 15){
    65. Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "say There is no server lag");
    66. }
    67. else {
    68. Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "say Unable to determine if server is lagging");
    69. Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "say Please contact an Admin");
    70. }
    71.  
    72.  
    73.  
    74. }
    75. }
    76.  

    And even though im running a local server, with no players, on a brand new computer (i7, SSD, 16 GB RAM, dedicated graphics) plenty to run a server at full TPS with no players, the TPS output is 17, 18, 19, but never 20. Something i did wrong?
     
  15. Even I got 20 tps with that code =)
    But I was monitoring it each second... the log from my first post in this thread has 20tps :p
    Also, your "else" to that TPS comparison condition will *never* trigger :)
     
  16. Offline

    zeeveener

    Is currentSec initialized somewhere else or are you just using those as examples where we would have to initialize them ourselves. Like the ticks int then using ticks++. Couldn't that cause problems because if it's not initialized it uses a random number?

    Just curious. Other than that I have no questions/concerns/pancake mix
     
  17. zeeveener
    No, code is copypastable, those variables are defined here:
    Code:
    getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable()
    {
         long sec;
         long currentSec;
         int ticks;
         int delay;
    
    //....
    And they're default 0 because they're primitives and they can't be null.
    If they were objects they'd be null.
     
  18. Offline

    zeeveener

    I saw that they were declared lol. I meant having = 0; afterwards. I thought that if you didn't initialize a variable, it chose a random number.

    Although, come to think about it, i might be referring to my C++ course because I know that language behaves like that... The two are just so similar sometimes...
     
  19. C++ asigns to a random number if you don't asign a specific value ? :confused: that's kinda stupid...
     
  20. Actually, if I understood that correctly, not initializing something in C++ just gives it the value that happens to be at that memory address at that point. Like, another process or whatever used to use that memory space previously, declared that as free memory, and if you go ahead and point to that address then without giving it a valu of yours (0), it just leaves the current value there, thus giving you a somewhat "random" result.
     
    zeeveener likes this.
  21. Offline

    Techtony96

    OK, I removed the else statement, but how would i change this code to make it run every second. It seems that having it run every 5 mins seems to mess it up.
     
  22. The code triggers every tick... and I've placed comments which parts of the code trigger less frequently :)

    You could check the TPS each second but I don't really recommend it because any lag spike would trigger it... it's good as is, detecting constant lag, not lag spikes.
     
Thread Status:
Not open for further replies.

Share This Page