I'm working on a spring boot project about electronic contract recently.And There has an interface of raiseContract().Considering that the traffic of this interface will be large in the future,My Leader let me use Hystrix to defender it.And I did not use it before.I am learning it and trying to use it on the interface.I use ThreadPool Isolation Strategy and I don't konw how to set
the parameter of coreSize reasonable in ThreadPoolProperties.In other words,I want to know what should I follow to set it.
I did a lot of research,but I did not get the answer.All of Answer is about the meaning of coreSize,maxQueueSize etc.
Here is my code:
#HystrixCommand(
groupKey = "contractGroup",
commandKey = "raiseContract",
fallbackMethod = "raiseContractFallback",
threadPoolProperties = {
#HystrixProperty(name = "coreSize", value = "20"),
#HystrixProperty(name = "maxQueueSize", value = "150"),
#HystrixProperty(name = "queueSizeRejectionThreshold", value = "100")},
commandProperties = {
#HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "15000"),
#HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"),
#HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
#HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "3000"),
#HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "20")
})
As you are already aware of, there are 3 main threadPool configurations:
coreSize: Number of threads that will be maintained in the pool
maxSize: Defines how much extra threads are allowed in case need arises.
maxQueueSize: Queue size of the tasks
Now lets start with an example. Assume there is a service using hystrix, call it HystrixService, for which coreSize = maxSize = n and maxQueueSize = -1 (default case). This means at a time at most 'n' tasks will be executed. Any extra task that is coming will be rejected (fallback will be executed).
So, in ideal scenario, you have to ensure that this HystrixService doesn't reject any request coming to it. You need to know at max how many requests can there be on HystrixService. So if throughput on HystrixService is 10 Requests per second, then max concurrent requests on HystrixService can be 10. Now suppose latency of HystrixService is 2 sec, then by the time it responds to first 10 requests, 10 more requests will come. i.e. total requests = 2 * 10 = 20. So coreSize in this case should be 20.
This is same as mentioned in hystrix documentation,
coreSize = Peak Request per sec × P99 latency + some breathing room
Now, you can keep maxSize and queueSize a bit high, so that it doesn't reject requests, in case there are sudden throughput spikes on your service.
Related
Please help I was trying to call watson assistant endpoint
https://gateway.watsonplatform.net/assistant/api/v1/workspaces/myworkspace/logs?version=2018-09-20 to get all the list of events
and filter by date range using this params
var param =
{ workspace_id: '{myworkspace}',
page_limit: 100000,
filter: 'response_timestamp%3C2018-17-12,response_timestamp%3E2019-01-01'}
apparently I got any empty response below.
{
"logs": [],
"pagination": {}
}
Couple of things to check.
1. You have 2018-17-12 which is a metric date. This translates to "12th day of the 17th month of 2018".
2. Assuming the date should be a valid one, your search says "Documents that are Before 17th Dec 2018 and after 1st Jan 2019". Which would return no documents.
3. Logs are only generated when you call the message() method through the API. So check your logging page in the tooling to see if you even have logs.
4. If you have a lite account logs are only stored for 7 days and then deleted. To keep logs longer you need to upgrade to a standard account.
Although not directly related to your issue, be aware that page_limit has an upper hard coded limit (IIRC 200-300?). So you may ask for 100,000 records, but it won't give it to you.
This is sample python code (unsupported) that is using pagination to read the logs:
from watson_developer_cloud import AssistantV1
username = '...'
password = '...'
workspace_id = '....'
url = '...'
version = '2018-09-20'
c = AssistantV1(url=url, version=version, username=username, password=password)
totalpages = 999
pagelimit = 200
logs = []
page_count = 1
cursor = None
count = 0
x = { 'pagination': 'DUMMY' }
while x['pagination']:
if page_count > totalpages:
break
print('Reading page {}. '.format(page_count), end='')
x = c.list_logs(workspace_id=workspace_id,cursor=cursor,page_limit=pagelimit)
if x is None: break
print('Status: {}'.format(x.get_status_code()))
x = x.get_result()
logs.append(x['logs'])
count = count + len(x['logs'])
page_count = page_count + 1
if 'pagination' in x and 'next_url' in x['pagination']:
p = x['pagination']['next_url']
u = urlparse(p)
query = parse_qs(u.query)
cursor = query['cursor'][0]
Your logs object should contain the logs.
I believe the limit is 500, and then we return a pagination URL so you can get the next 500. I dont think this is the issue but once you start getting logs back its good to know
so while building a mobile game with Corona SDK i am encountering some problems now and then. One of them I didn't seem to solve :
When spawning display objects in a loop, there seems to randomly appear a positional difference between two of the objects in a row.
At first, I thought this was due to large chunks of code that were executed between the actual spawning and the start of the transition, but then I managed to reproduce the same problem in few lines :
local rectangleLoopTimer;
local counter = 0;
local rectangleArray = {}
local function rectangleLoop()
counter = counter + 1
local thisRectangle = display.newRect(1, 1, 216, 400)
thisRectangle.anchorX = 0
table.insert(rectangleArray, thisRectangle)
transition.to(
thisRectangle,
{
time = 5000,
x = thisRectangle.x + 1080,
onComplete = function()
display.remove(thisRectangle)
table.remove(rectangleArray, counter)
end
}
)
end
rectangleLoopTimer = timer.performWithDelay(985, rectangleLoop, 0)
If one executes this, then one sees what I mean, so what do you think why this happens? I appreciate every answer!
Greetings, Nils
EDIT:
This also produces the same problem :
local rectangleLoopTimer;
local counter = 0
local rectangleArray = {}
local thisRectangle
local function rectangleLoop()
counter = counter + 1
thisRectangle = display.newRect(1, 1, 216, 400)
thisRectangle.anchorX = 0
thisRectangle.lastTime = 0
thisRectangle.rate = 216
table.insert(rectangleArray, thisRectangle)
thisRectangle.lastTime = system.getTimer()
thisRectangle.enterFrame = function(self, event)
local curTime = system.getTimer()
local dt = curTime - self.lastTime
self.lastTime = curTime
local dx = self.rate * dt / 1000
self.x = self.x + dx
end
Runtime:addEventListener("enterFrame", thisRectangle)
end
rectangleLoopTimer = timer.performWithDelay(1000, rectangleLoop, 0)
RE-EDIT:
This code also produces the same problem, albeit using framerate independent animation. The issue is getting emphasized when increasing the speed of the loop as in the code below :
local loopSpeed = 306
local loopTimerSpeed = 1000
local gapTable = {}
local gapLoopTimer
local frameTime
local gap
--enterFrame for time only
local function frameTime(event)
frameTime = system.getTimer()
end
--enterFrame
local function enterFrame(self, event)
local deltaTime = frameTime - self.time
print(deltaTime/1000)
self.time = frameTime
local speed = self.rate * deltaTime / 1000
self:translate(speed, 0)
end
--loop speed function
local function setLoopSpeed(factor)
loopSpeed = loopSpeed * factor
loopTimerSpeed = loopTimerSpeed / factor
end
--set the loop speed
setLoopSpeed(3)
--loop to create gaps
local function createGap()
gap = display.newRect(1, 1, 308, 442)
gap.time = system.getTimer()
gap.anchorX = 1
gap.anchorY = 0
--animation
gap.rate = loopSpeed
gap.enterFrame = enterFrame
Runtime:addEventListener("enterFrame", gap)
--fill table for cleaning up
table.insert(gapTable, gap)
--cleaning up
for i = #gapTable, 1, -1 do
local thisGap = gapTable[i]
if thisGap.x > display.contentWidth + 500 then
display.remove(thisGap)
table.remove(gapTable, i)
Runtime:removeEventListener("enterFrame", thisGap)
end
thisGap = nil
end
end
Runtime:addEventListener("enterFrame", frameTime)
gapLoopTimer = timer.performWithDelay(
loopTimerSpeed,
createGap,
0
)
This is a very common problem with transitions, and [to me] a bug in Corona SDK.
The important thing to note is how transitions work.
Transitions are nothing else than a table with references to objects and information about what should be done to them each frame.
Each frame such object is retrieved and current time is used to calculate the difference that should be applies to the values of the object, as specified in the transition itself.
This basically means that if you ask Corona to move an object from x = 0 to x = 100 in time = 100. Each frame, Corona will take that information, take current time, and will calculate the x value of your object.
The issue here is, that the current time taken, is current time at a time of calculation, and not time of the frame. It means, that if you have a lot of transitions, it could be quite a few milliseconds between first and last of the transitions within one frame. This will result in different positions within same frame.
If Corona would take frame time [so time at the beginning of the frame] it would use the same value to calculate everything, and no matter how many objects you would be transitioning from A to B, all of them would appear in the same place in all of the frames.
The easiest way to fix this, would be to handle transitions manually in enterFrame or use a library which does it for you, for example: AKTween.
Hope this helps.
EDIT:
Based on your additional code and comments, I think this should work as you wanted. Please forgive me the code quality, I wrote it from memory and didn't test it in Corona.
local rectangleLoopTimer;
local allRectangles = display.newGroup()
local lastTime = system.getTimer()
local function enterFrame()
local curTime = system.getTimer()
local dt = curTime - lastTime
lastTime = curTime
for i = allRectangles.numChildren, 1 do
local rect = allRectangles[i]
local dx = rect.rate * dt / 1000
rect.x = rect.x + dx
end
end
Runtime:addEventListener("enterFrame", enterFrame)
local function createRectangle()
local thisRectangle = display.newRect(1, 1, 216, 400)
thisRectangle.anchorX = 0
thisRectangle.lastTime = 0
thisRectangle.rate = 216
allRectangles:insert(thisRectangle)
end
timer.performWithDelay(1000, createRectangle, 0)
EDIT AFTER RE-EDIT of the post:
You have time set in enterFrame listener, but you don't actually know when it's going to be called. I would not count on the order of functions called during enterFrame stage.
If you don't need futher reference to rects use code below
local rand = math.random
local function rectangleLoop()
local thisRectangle = display.newRect(1, 1, 216, 400)
thisRectangle.anchorX = 0
thisRectangle:setFillColor(rand(), rand(), rand())
transition.to(thisRectangle, {time=5000,x=thisRectangle.x + 1080, onComplete=display.remove})
end
rectangleLoopTimer = timer.performWithDelay(985, rectangleLoop, 0)
Do you need use table to store rects?
I have following scenario which has two requests (RequestOne and RequestTwo). It is setup to run for 3 users and 1 repetition. The simulation should have taken at least 20 seconds to finish as I am using 20 seconds as pacing. However, every time I run it, it finishes in less than 20 seconds. I tried with different values for pacing as well.
val Workload = scenario("Load Test")
.repeat(1, "repetition") {
pace(20 seconds)
.exitBlockOnFail {
.feed(requestIdFeeder)
.group("Load Test") {
.exec(session => {
session.set("url", spURL)
})
.group("RequestOne") {exec(requestOne)}
.feed(requestIdFeeder)
.group("RequestTwo") {exec(requestTwo)}
}
}
}
setUp(Workload.inject(atOnceUsers(3))).protocols(httpProtocol)
output
Simulation com.performance.LoadTest completed in 11 seconds
Found the problem. I used only 1 repetition so the scenario didn't need to wait for the 20sec pacing to complete and it exited early. Setting repetition to > 1 helped achieve the desired rate.
val Workload = scenario("Load Test")
.repeat(10, "repetition") {
pace(20 seconds)
.exitBlockOnFail {
So, if you want to achieve fixed number of transactions in your simulation, use repetition, otherwise use "forever (" as mentioned in gatling docoumentation to achieve consistent rate.
val Workload = scenario("Load Test")
.forever (
pace(20 seconds)
.exitBlockOnFail {
I'm a musician attempting to write a music reading programme for guitarists.
I want to time two consecutive sounds so that the first stops when the second begins. Each should last a predetermined duration (defined in this example as 72 in 60000/72). As a beginner coder I'm struggling and would really appreciate any help.
-- AUDIO 1 --
local aa = audio.loadStream(sounds/chord1.mp3)
audio.play(aa)
-- TIMER 1 --
local timeLimit = 1
local function timerDown()
timeLimit = timeLimit-1
if(timeLimit==0)then
end
end
timer.performWithDelay( 60000/72, timerDown, timeLimit )
-- TIMER 2 --
local timeLimit = 1
local function timerDown()
timeLimit = timeLimit-1
if(timeLimit==0)then
-- AUDIO 2 --
local aa = audio.loadStream(sounds/chord2.mp3])
audio.play(aa)
end
end
timer.performWithDelay( 60000/72, timerDown, timeLimit )
There are a few things to note here. Sorry for the wall of text!
Strings (text)
Must be enclosed in quotes.
local aa = audio.loadStream(sounds/chord1.mp3)
becomes:
local aa = audio.loadStream('sounds/chord1.mp3')
Magic numbers
Values which aren't explained anywhere should be avoided. They make code harder to understand and harder to maintain or modify.
timer.performWithDelay(60000/72, timerDown, timeLimit)
becomes:
-- Might be slight overkill but hopefully you get the idea!
local beatsToPlay = 10
local beatsPerMinute = 72
local millisPerMinute = 60 * 1000
local playTimeMinutes = beatsToPlay / beatsPerMinute
local playTimeMillis = playTimeMinutes * millisPerMinute
timer.performWithDelay(playTimeMillis, timerDown, timeLimit)
Corona API
It is an invaluable skill when programming to be able to read and understand documentation. Corona's API is documented here.
audio.loadStream()'s docs tell you that it returns an audio handle which you can use to play sounds which is what you've got already. It also reminds you that you should dispose of the handle when you are done so you'll need to add that in.
timer.performWithDelay()'s docs tell you that it needs the delay time in milliseconds and a listener which is what will be activated at that time, so you will need to write a listener of some description. If you follow the link to listener or if you look at the examples further down the page then you'll see that a simple function will suffice.
audio.play() is fine as it is but if you read the docs then it informs you of some more functionality which you could use to your advantage. Namely the options parameter, which includes duration and onComplete. duration is how long - in millis - to play the sound. onComplete is a listener which will be triggered when the sound has finished playing.
The result
Using timers only:
local function playAndQueue(handle, playTime, queuedHandle, queuedPlayTime)
audio.play(handle, { duration = playTime })
timer.performWithDelay(playTime, function(event)
audio.dispose(handle)
audio.play(queuedHandle, { duration = queuedPlayTime })
end)
timer.performWithDelay(playTime + queuedPlayTime, function(event)
audio.dispose(queuedHandle)
end)
end
local audioHandle1 = audio.loadStream('sounds/chord1.mp3')
local audioHandle2 = audio.loadStream('sounds/chord2.mp3')
local beatsToPlay = 10
local beatsPerMinute = 72
local millisPerMinute = 60 * 1000
local playTimeMinutes = beatsToPlay / beatsPerMinute
local playTimeMillis = playTimeMinutes * millisPerMinute
playAndQueue(audioHandle1, playTimeMillis, audioHandle2, playTimeMillis)
Using onComplete:
local function playAndQueue(handle, playTime, queuedHandle, queuedPlayTime)
-- Before we can set the 1st audio playing we have to define what happens
-- when it is done (disposes self and starts the 2nd audio).
-- Before we can start the 2nd audio we have to define what happens when
-- it is done (disposes of the 2nd audio handle)
local queuedCallback = function(event)
audio.dispose(queuedHandle)
end
local callback = function(event)
audio.dispose(handle)
local queuedOpts = {
duration = queuedPlayTime,
onComplete = queuedCallback
}
audio.play(queuedHandle, queuedOpts)
end
local opts = {
duration = playTime,
onComplete = callback
}
audio.play(handle, opts)
end
local audioHandle1 = audio.loadStream('sounds/chord1.mp3')
local audioHandle2 = audio.loadStream('sounds/chord2.mp3')
local beatsToPlay = 10
local beatsPerMinute = 72
local millisPerMinute = 60 * 1000
local playTimeMinutes = beatsToPlay / beatsPerMinute
local playTimeMillis = playTimeMinutes * millisPerMinute
playAndQueue(audioHandle1, playTimeMillis, audioHandle2, playTimeMillis)
You might find that using onComplete works out better than pure timers since you might end up disposing the audio handle just before is is done being used for playback (and causing errors). I haven't had any experience with Corona so I'm not sure how robust its timer or audio libraries are.
I am trying to write an indicator originally from MT4 into NT7.
I have the following calculations in MT4:
dayi = iBarShift(Symbol(), myPeriod, Time[i], false);
Q = (iHigh(Symbol(), myPeriod,dayi+1) - iLow(Symbol(),myPeriod,dayi+1));
L = iLow(NULL,myPeriod,dayi+1);
H = iHigh(NULL,myPeriod,dayi+1);
O = iOpen(NULL,myPeriod,dayi+1);
C = iClose(NULL,myPeriod,dayi+1);
myperiod is a variable where I place the period in minutes (1440 = 1day).
What are the equivalent functions in NT7 to iBarShift, iHigh and so on?
Thanks in advance
For NinjaTrader:
iLow = Low or Lows for multi-time frame
iHigh = High or Highs
iOpen = Open or Opens
iClose = Close or Closes
So an example would be
double low = Low[0]; // Gets the low of the bar at index 0, or the last fully formed bar (If CalculateOnBarClose = true)
In order to make sure you are working on the 1440 minute time frame, you will need to add the following in the Initialize() method:
Add(PeriodType.Minute, 1440);
If there are no Add statements prior to this one, it will place it at index 1 (O being the chart default index) in a 2 dimensional array. So to access the low of the 1440 minute bar at index 0 would be:
double low = Lows[1][0];
For iBarShift look at
int barIndex = Bars.GetBar(time);
which will give you the index of the bar with the matching time. If you need to use this function on the 1440 bars (or other ones), use the BarsArray property to access the correct Bar object and then use the GetBar method on it. For example:
int barIndex = BarsArray[1].GetBar(time);
Hope that helps.