October/November Development Objectives

Development, Research, and Testing Updates.

Re: October/November Development Objectives

Postby Eruptor » October 31st, 2015, 3:15 pm

Hi!
Sorry for going slightly off topic from the October/November Development Objectives.

It's a long time since I contributed to this site, but have followed your work on and off since 2009 when I left ANH. I have since then used the 2009 SWGANH server as a playground when I wanted to test ideas I had. (Yes, still addicted to SWG and I like to program).

I would say lei2 is correct about his/her concern about the architecture. Remove the polling strategy!
Trying to control a game engine with waits or CPU constrains is just an attempt to hide bad design, IMHO.

I may have a different approach regarding the selection of the OS, but that's mostly because I wanted to expand on the OS I was most comfortable with (Windows). I don't think the OS itself is of any major concern here. Just go for the one you like and understand.

Even though, one of my first actions was, just like lei2, to get rid of boost; not because it was bad but because people had implemented functionality without understanding how it worked, and then created errors hard to find. Can expand more about this, but this thread is not the place for that.

Keep up the good work.

/Eru
Eruptor
 
Posts: 15
Joined: January 24th, 2009, 3:07 pm

Re: October/November Development Objectives

Postby Obi-Two » November 1st, 2015, 1:09 pm

Eruptor wrote:Hi!
Sorry for going slightly off topic from the October/November Development Objectives.

I would say lei2 is correct about his/her concern about the architecture. Remove the polling strategy!
Trying to control a game engine with waits or CPU constrains is just an attempt to hide bad design, IMHO.

I may have a different approach regarding the selection of the OS, but that's mostly because I wanted to expand on the OS I was most comfortable with (Windows). I don't think the OS itself is of any major concern here. Just go for the one you like and understand.

Even though, one of my first actions was, just like lei2, to get rid of boost; not because it was bad but because people had implemented functionality without understanding how it worked, and then created errors hard to find. Can expand more about this, but this thread is not the place for that.


Hey Eruptor,
Good to see you still around :D Don't worry about going off topic, its nice to get input from everyone, there is a lot of bad design in this project I wish I have the skill to start it over, but I feel that would be a massive ask and a huge time sink, look what happend the last time that was tryed we just lost 3/6 years (I loose count). I will start some development threads in the week to cover the deps as there must be new alternatives by now, like the my sql connectors seem a little flaky, I had trouble getting then to complie proberly on windows, ect ect.

I'm hopeful that once we get this a littel more stable we can start to look in to some of the bad design and rework it form the inside out, but first thigs first ;)

lei2 wrote:Btw for the testcenter ... did you try apt-get install cpulimit? https://wiki.ubuntuusers.de/cpulimit
Might help to tame the beasts a bit, login and ping do not really need more than a few cpu%, chat and connection might work with 10% each, guess tat should run with 20% but tutorial and maybe corellia and naboo would be good with 10%.

Lei2, I have not but I shall, it has to be worth a go, :D

Many thanks to you all,
Obi
Obi-Two

Quality Assurance
Star Wars Galaxies:A new hope
there is another...

Server by : Hostwind
Project : SWGANHServices/SWGANHJava
Obi-Two
SWG:ANH Staff
 
Posts: 246
Joined: January 3rd, 2009, 9:37 am
Location: Manchester, England
SWG Official Server: Ahazi

Re: October/November Development Objectives

Postby Obi-Two » November 3rd, 2015, 3:46 pm

Hey Eruptor,
I've just re read your post and this stuck out to me,
Eruptor wrote:Even though, one of my first actions was, just like lei2, to get rid of boost; not because it was bad but because people had implemented functionality without understanding how it worked, and then created errors hard to find. Can expand more about this, but this thread is not the place for that.

Keep up the good work.

/Eru

Dose this mean you have already removed boost?

what did y ou used instead? can we have a copy?, Love you Obi :D
Obi-Two

Quality Assurance
Star Wars Galaxies:A new hope
there is another...

Server by : Hostwind
Project : SWGANHServices/SWGANHJava
Obi-Two
SWG:ANH Staff
 
Posts: 246
Joined: January 3rd, 2009, 9:37 am
Location: Manchester, England
SWG Official Server: Ahazi

Re: October/November Development Objectives

Postby Eruptor » November 4th, 2015, 4:05 am

Hi Obi-two!

The server I use is based on the first version from 2009 and have since then been developed in another direction than the official ANH server. Back then I replaced boost with plain C++ because boost was poorly implemented and hard to debug.
The first version (-2009) only used a limited amount of boost compared to the second server ANH started with 2009-2010, as far as I can recall. I was never part of the development of that second server or any later versions.

I have since then heavily changed the framework, among other things I rewrote the network layer and removed the polling strategy. The server framework now (actually since late 2009) use multithreading with message based signaling internally. Server-server communication is done with UDP or optional with TCP. My implementation depends heavily on Windows and C++11.

And I think ANH has restarted twice since then, so there isn't much in common regarding the code.
We can always share ideas or experience made.

As an example, when I replaced the polling with event based multithreading the load time for Tatooine went from about 10 min to about 1 min, without doing any tricks with how the data was selected or loaded from the MySQL-server. So based on my experience I recommend you to remove all polling.
The above timings are based on my hardware at 2009.

/Eru
Eruptor
 
Posts: 15
Joined: January 24th, 2009, 3:07 pm

Re: October/November Development Objectives

Postby lei2 » November 4th, 2015, 6:47 am

Hi Eru,

good to see you still keeping an eye on this. Id not say its off topic since it def hits the spot : )
And same here with SWG and programming.

Eruptor wrote:I would say lei2 is correct about his/her concern about the architecture. Remove the polling strategy!
Trying to control a game engine with waits or CPU constrains is just an attempt to hide bad design, IMHO.


Not only in yours. But as I learned in the last days, it is not easy to overcome. Most core parts of the network need to be redesigned for that, Database will be an issue of its own. I completely removed it from the base servers since it was used quite inappropriate there. In that process network issues popped up and that is what I was on the last days. Things like a per process central session management, message routing, soft reconnect ... just to name a few.

Eruptor wrote:I may have a different approach regarding the selection of the OS, but that's mostly because I wanted to expand on the OS I was most comfortable with (Windows). I don't think the OS itself is of any major concern here. Just go for the one you like and understand.


I guess we all have our preferences here. But the point is on which target the things will run and Im afraid for realistic operation there is not really any alternative to linux. IMHO an early decision for that would have been a great benefit for the project.

Eruptor wrote:Even though, one of my first actions was, just like lei2, to get rid of boost; not because it was bad but because people had implemented functionality without understanding how it worked, and then created errors hard to find. Can expand more about this, but this thread is not the place for that.
Keep up the good work.
/Eru


Yep, I'll do my best : ) But am afraid it will take some time until something publishable comes out. For the next days authentication and char creation is on table since I feel I have to learn a bit more about this part than I can read from the code. Also in char creation I wonder why from time to time the carousel works but most time it doesnt.

Also - just to stay a bit on topic - an issue of the last but one month, the start language for wooks. This can be solved in ~/mmoserverdb/swganh/procedures/sp_CharacterCreate.sql:

Code: Select all
  SELECT id from race where race.name like shortSpecies into race_id;

  DECLARE language_id INT;
  SET language_id = 1;

  IF raceId =  1 THEN SET  language_id = 165; END IF; //rodian
  IF raceId =  2 THEN SET  language_id = 167; END IF; //trando
  IF raceId =  3 THEN SET  language_id = 169; END IF; //moncal
  IF raceId =  4 THEN SET  language_id = 171; END IF; //wookie
  IF raceId =  5 THEN SET  language_id = 173; END IF; //bothan
  IF raceId =  6 THEN SET  language_id = 175; END IF; //twilek
  IF raceId =  7 THEN SET  language_id = 177; END IF; //zabrak
  IF raceId = 33 THEN SET  language_id = 181; END IF; //ithorian
  IF raceId = 49 THEN SET  language_id = 183; END IF; //sullust


  SELECT skill_id from skills where skill_name like start_profession INTO profession_id;

  -- Don't set any default skills or XP when creating player in the Tutorial.

and same file a bit below
Code: Select all
  INSERT INTO datapads VALUES (datapad_id,1);
  INSERT INTO character_attributes VALUES (character_id, 1, t_health, t_strength, t_constitution, t_action, t_quickness, t_stamina, t_mind, t_focus, t_willpower, t_health, t_strength, t_constitution, t_action, t_quickness, t_stamina, t_mind, t_focus, t_willpower, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, battlefatigue,0,0,NULL,0,0,language_id,0,0,0,3);


Just another small step. Hopefully one day its far enough to put things like house signs on the table.

Greetz, lei
Last edited by lei2 on November 5th, 2015, 12:30 pm, edited 1 time in total.
lei2
SWG:ANH Staff
 
Posts: 25
Joined: September 23rd, 2015, 1:11 pm
SWG Official Server: Farstar

Re: October/November Development Objectives

Postby Obi-Two » November 5th, 2015, 6:33 am

You guys rock :D

I've created a forum for developmetn discussion, and a topic for deps discussion here

I'll make the changes to the sql and test it tonight.

Eru. thats a shame, :( but yeah the current ptroject is a but of a hybrid of the former to (I think!)
its a bit hard to keep track

Obi
Obi-Two

Quality Assurance
Star Wars Galaxies:A new hope
there is another...

Server by : Hostwind
Project : SWGANHServices/SWGANHJava
Obi-Two
SWG:ANH Staff
 
Posts: 246
Joined: January 3rd, 2009, 9:37 am
Location: Manchester, England
SWG Official Server: Ahazi

Re: October/November Development Objectives

Postby Obi-Two » November 6th, 2015, 6:32 am

I added the sql changes bit kept getting an eorror, something to do with a missing If,

Code: Select all
      IF raceId = 0 THEN SET language_id = 1; -- basic

      elseIF raceId =  1 THEN SET  language_id = 165; -- rodian
      elseIF raceId =  2 THEN SET  language_id = 167; -- trando
      elseIF raceId =  3 THEN SET  language_id = 169; -- moncal
      elseIF raceId =  4 THEN SET  language_id = 171; -- wookie
      elseIF raceId =  5 THEN SET  language_id = 173; -- bothan
      elseIF raceId =  6 THEN SET  language_id = 175; -- twilek
      elseIF raceId =  7 THEN SET  language_id = 177; -- zabrak
      elseIF raceId = 33 THEN SET  language_id = 181; -- ithorian
      elseIF raceId = 49 THEN SET  language_id = 183; -- sullust
END IF;


i changed it to this and it clearded the errors, just need to test now

EDIT: this was gave me another error (the server rejects all charactor names :D)
Obi-Two

Quality Assurance
Star Wars Galaxies:A new hope
there is another...

Server by : Hostwind
Project : SWGANHServices/SWGANHJava
Obi-Two
SWG:ANH Staff
 
Posts: 246
Joined: January 3rd, 2009, 9:37 am
Location: Manchester, England
SWG Official Server: Ahazi

Re: October/November Development Objectives

Postby lei2 » November 7th, 2015, 3:05 pm

One timing issue we already were on was the ActiveObject in ~src/Utils.

What we have here is a class that spins off a thread to monitor a concurrent queue where by method send foreign method(s) are inserted. These then are pop'ed executed in the AO thread. AO is used in SocketWriteThread, DatabaseWorkerThread and EventDispatcher to run a part of their methods async to their common working threads.

As it is implemented, the condition while waiting is peeking the queue over and over again. That leads to cpu bugging. Even if mentioned in the class comment, I do not suppose that this is really meant as a feature of this class.

So I reimplemented it, using std::thread, condition and chrono to replace the boost classes.

~src/Utils/ActiveObject.h:
Code: Select all
/*
---------------------------------------------------------------------------------------
This source file is part of SWG:ANH (Star Wars Galaxies - A New Hope - Server Emulator)

For more information, visit http://www.swganh.com

Copyright (c) 2006 - 2015 The SWG:ANH Team /Unofficial Hope Edit
---------------------------------------------------------------------------------------
Use of this source code is governed by the GPL v3 license that can be found
in the COPYING file or at http://www.gnu.org/licenses/gpl-3.0.html

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
---------------------------------------------------------------------------------------
*/

#ifndef SRC_UTILS_ACTIVEOBJECT_H_
#define SRC_UTILS_ACTIVEOBJECT_H_

#include <functional>
#include <memory>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
#include "logger.h"

#include <tbb/concurrent_queue.h>

namespace utils {

class ActiveObject {
public:
    // Messages are implemented as std::function to allow maximum flexibility for
    // how a message can be created with support for functions, functors, class members,
    // and most importantly lambdas.

    typedef std::function<void()> AO_Message;

public:
public:
    // Messages are implemented as std::function to allow maximum flexibility for
    // how a message can be created with support for functions, functors, class members,
    // and most importantly lambdas.

    typedef std::function<void()> AO_Message;

public:
    // Default constructor kicks off the private thread that listens for incoming messages.
    ActiveObject(){

        done_ = false;
        thread_ = std::move(std::thread([=] { this->Run(); }));

        }

    // Default destructor sends an end message and waits for the private thread to complete.
    ~ActiveObject(){
        Send([&] { done_ = true; });
        thread_.join();
        }

    void Send(AO_Message message){
        message_queue_.push(message);
        condition_.notify_one();
        }

private:
    /// Runs the ActiveObject's message loop until an end message is received.
    void Run(){
        AO_Message message;

        std::unique_lock<std::mutex> lock(mutex_);

        while (! done_) {

                condition_.wait_for(lock, std::chrono::milliseconds(1000));

                if(message_queue_.try_pop(message)) {
                        message();
                        }

                }//while

        }

    tbb::concurrent_queue<AO_Message> message_queue_;

    std::thread                         thread_;
    std::condition_variable        condition_;
    std::mutex                          mutex_;

    bool done_;
};
}  // namespace utils

#endif  // SRC_UTILS_ACTIVEOBJECT_H_


Since its a small class for comfort the replacing impl is done in the ActiveObject.h only, ActiveObject.cpp is to remove. Also this has effects to compile/link, from time to time I ran into issues because the libUtils.a wasnt in sync what cannot be case this way.

For testing the timeout is very high. In operation it would be a few ms only, this still needs evaluation.

The overall effect in cpu time usage for the servers is not that high, the other worker threads still bug it and also use the AO in a way that keeps it busy all the time. So just another small step but since it is a very central and intense used object an important one.

As I am limited in time a bit atm, I could do only frame tests. So better keep a copy of the original files ; )

And btw thanx for the green name, I feel honored to be part of the team and hope I can help to give TC a go in not that far future.

Greetz, lei
lei2
SWG:ANH Staff
 
Posts: 25
Joined: September 23rd, 2015, 1:11 pm
SWG Official Server: Farstar

Re: October/November Development Objectives

Postby Eruptor » November 7th, 2015, 6:31 pm

Hi lei,

The condition variable implementation is the way to go, I just have one question and one suggestion.

Why using wait_for instead of wait?
If it's because you need to track changes to done_, then combine updates to done_ with a notify_one().
The wait_for will act as polling, and should not be needed since you use signaling via notify_one().

May I also suggest that you execute the condition.wait(...) after you have failed to pop a message.
This will ensure that you can continue to pop messages even if the system missed notifications.

My 2 cents...
/Eru
Eruptor
 
Posts: 15
Joined: January 24th, 2009, 3:07 pm

Re: October/November Development Objectives

Postby lei2 » November 8th, 2015, 8:43 am

Eruptor wrote:Hi lei,

The condition variable implementation is the way to go, I just have one question and one suggestion.

Why using wait_for instead of wait?
If it's because you need to track changes to done_, then combine updates to done_ with a notify_one().
The wait_for will act as polling, and should not be needed since you use signaling via notify_one().

May I also suggest that you execute the condition.wait(...) after you have failed to pop a message.
This will ensure that you can continue to pop messages even if the system missed notifications.

My 2 cents...
/Eru


Hey Eru,

things happen all the time, notifys may be missed. So better to have a timeout too. With condition linked to pthread, chrono should not be polled, the timeout is event driven. The third arg in wait_for would make the polled condition, as it was used in the implementation with boost.

My intention for the overall effect of the delay was to flaten system load in case of message bursts, scaleable by timeout value. It would have a max opened "throttle" while messages come in, but then slow down and work off one by one per timeout. As for examples sessions are pushed into in cycle, the effect is hardly noticeable, the first session will raise load by 5%.

I guess we will need to keep an eye on the AO since the way it works best - with delay our as you suggest working off the whole queue in a row - depends a bit on the things done in the messages and the - if one will call it so - producer threads. To get a way out of the cycle hell the AOmessage'd classes could get an idle flag, by that they are sorted into a secondary queue:

Code: Select all
 
active_.Send( [=] {                             
          session->ProcessWriteThread();         
          if(session->mIdle)  mAsyncSessionIdleQueue.push(session);
          else  mAsyncSessionQueue.push(session);     
           }  );



and then from time to time pop all the idle queue and Send it back into procession.

Code: Select all
if(ctr++ > 50) {  //get session back from the idle queue
          while(mAsyncSessionIdleQueue.pop(session)){
                  active_.Send( [=] {
                             session->ProcessWriteThread();
                              mAsyncSessionQueue.push(session);
                              }  );

                 }
         ctr=0;
         }


Doing so, AO could then work off all packets in queue in a row as well. This secondary queue has a noticeable effect, with it the load for few most idle sessions just increase 1-2% for a short time period.
The ctr is an bit a poor control, its just demonstrate the idea and to verify the effect. For the database worker a similar way might fit.
Greetz, lei
lei2
SWG:ANH Staff
 
Posts: 25
Joined: September 23rd, 2015, 1:11 pm
SWG Official Server: Farstar

PreviousNext

Return to Developer's Datapad

Who is online

Users browsing this forum: No registered users and 1 guest

cron