Sunday, February 26, 2017

JForex 3 with Scala & SBT

Leave a Comment

I'm trying to use the JForex-3 SDK from Scala / SBT.

My build.sbt looks like:

name := "tmp" version := "1.0" scalaVersion := "2.12.1"  resolvers += "Dukascopy" at "https://www.dukascopy.com/client/jforexlib/publicrepo/" libraryDependencies ++= Seq(   "com.dukascopy.dds2" % "DDS2-jClient-JForex" % "3.1.2",   "com.dukascopy.api" % "JForex-API" % "2.13.30" ) 

When importing import com.dukascopy.api.system there is only "tester" available. I cannot figure out what happens with the rest https://www.dukascopy.com/client/javadoc3/

Can someone help here ?

1 Answers

Answers 1

Downgrading the version of the first library dependency solves the problem. Downgrade it to version 3.0.18

name := "tmp"  version := "1.0"  scalaVersion := "2.12.1"  resolvers += "Dukascopy" at "https://www.dukascopy.com/client/jforexlib/publicrepo/"  libraryDependencies ++= Seq(   "com.dukascopy.dds2" % "DDS2-jClient-JForex" % "3.0.18",   "com.dukascopy.api" % "JForex-API" % "2.13.30" ) 
Read More

Saturday, February 25, 2017

How to know which stage of a job is currently running in Apache Spark?

Leave a Comment

Consider I have a job as follow in Spark;

CSV File ==> Filter By A Column ==> Taking Sample ==> Save As JSON

Now my requirement is how do I know which step(Fetching file or Filtering or Sampling) of the job is currently executing programatically (Preferably using Java API)? Is there any way for this?

I can track Job,Stage and Task using SparkListener class. And it can be done like tracking a stage Id. But how to know which stage Id is for which step in the job chain.

What I want to send a notification to user when consider Filter By A Column is completed. For that I made a class that extends SparkListener class. But I can not find out from where I can get the name of currently executing transformation name. Is it possible to track at all?

public class ProgressListener extends SparkListener{    @Override   public void onJobStart(SparkListenerJobStart jobStart)   {    }    @Override   public void onStageSubmitted(SparkListenerStageSubmitted stageSubmitted)   {       //System.out.println("Stage Name : "+stageSubmitted.stageInfo().getStatusString()); giving action name only   }    @Override   public void onTaskStart(SparkListenerTaskStart taskStart)   {       //no such method like taskStart.name()   } } 

2 Answers

Answers 1

You cannot exactly know when, e.g., the filter operation starts or finishes.

That's because you have transformations (filter,map,...) and actions (count, foreach,...). Spark will put as many operations into one stage as possible. Then the stage is executed in parallel on the different partitions of your input. And here comes the problem.

Assume you have several workers and the following program

LOAD ==> MAP ==> FILTER ==> GROUP BY + Aggregation

This program will probably have two stages: the first stage will load the file and apply the map and filter. Then the output will be shuffled to create the groups. In the second stage the aggregation will be performed.

Now, the problem is, that you have several workers and each will process a portion of your input data in parallel. That is, every executor in your cluster will receive a copy of your program(the current stage) and execute this on the assigned partition.

You see, you will have multiple instances of your map and filter operators that are executed in parallel, but not necessarily at the same time. In an extreme case, worker 1 will finish with stage 1 before worker 20 has started at all (and therefore finish with its filter operation before worker 20).

For RDDs Spark uses the iterator model inside a stage. For Datasets in the latest Spark version however, they create a single loop over the partition and execute the transformations. This means that in this case Spark itself does not really know when a transformation operator finished for a single task!

Long story short:

  1. You are not able the know when an operation inside a stage finishes
  2. Even if you could, there are multiple instances that will finish at different times.

So, now I already had the same problem:

In our Piglet project (please allow some adverstisement ;-) ) we generate Spark code from Pig Latin scripts and wanted to profile the scripts. I ended up in inserting mapPartition operator between all user operators that will send the partition ID and the current time to a server which will evaluate the messages. However, this solution also has its limitations... and I'm not completely satisfied yet.

However, unless you are able to modify the programs I'm afraid you cannot achieve want you want.

Answers 2

Did you consider this option: http://spark.apache.org/docs/latest/monitoring.html
It seems you can use the following rest api to get a certain job state /applications/[app-id]/jobs/[job-id]

You can set the JobGroupId and JobGroupDescription so you can track what job group is being handled. i.e. setJobGroup

Assuming you'll call the JobGroupId "test"

sc.setJobGroup("1", "Test job") 

When you'll call the http://localhost:4040/api/v1/applications/[app-id]/jobs/[job-id]

You'll get a json with a descriptive name for that job:

{   "jobId" : 3,   "name" : "count at <console>:25",   "description" : "Test Job",   "submissionTime" : "2017-02-22T05:52:03.145GMT",   "completionTime" : "2017-02-22T05:52:13.429GMT",   "stageIds" : [ 3 ],   "jobGroup" : "1",   "status" : "SUCCEEDED",   "numTasks" : 4,   "numActiveTasks" : 0,   "numCompletedTasks" : 4,   "numSkippedTasks" : 0,   "numFailedTasks" : 0,   "numActiveStages" : 0,   "numCompletedStages" : 1,   "numSkippedStages" : 0,   "numFailedStages" : 0 } 
Read More

Rails 3 to 4 migration uniqueness validation issues

Leave a Comment

Context

We are migrating from Rails 3.2.12 to 4.0.2 and Ruby 1.9.3 to 2.1.8.

We have a lot of test coverage to accomplish the migration in the form of RSpec.

Issue

One of the spec that checks that a uniqueness validation on a Card model is failing.

validates :mobile, uniqueness: {scope: :program_member_id, message: I18n.t('models.card.error.cardholder_already_has_mobile')}, if: :mobile 

Where a program_member may only have one mobile: true card.

The spec creates 2 cards for the member, turns one into a mobile card, then expects the validation's message when doing so with the second card.

let(:program) { FactoryGirl.create(:program) } let(:card) { FactoryGirl.create(:card, program: program) }  context 'when cardholder already has a mobile card' do   it 'fails validation' do     card2 = FactoryGirl.create(:card, program: program)     program_member_user = FactoryGirl.create(:program_member_user, card_number: card2.cardnumber)     program_member = program_member_user.program_members.first      program_member.cards << card2     card2.update_attributes(:mobile => true)      program_member.cards << card     card.update_attributes(:mobile => true)      expect(card.errors.messages).to include(:mobile=>[I18n.t('models.card.error.cardholder_already_has_mobile')])   end end 

Expectation:

expected {} to include {:mobile=>["Cardholder already has a mobile card"]} 

When I go to our master branch, this spec passes.

The only factor that has changed from this spec working to failing is the Rails 3 to 4 migration.

Tried running the spec code in console only to find the member has 2 mobile cards and doing card.valid? returns true for both instances.

Question

Has anything changed in Rails 4 in regards to uniqueness validation or validation life cycle?

1 Answers

Answers 1

Alright so I'm onto something.

I created a test project using the same Ruby and Rails version.

https://github.com/frank184/test_uniquness

In this project, I would have a User model that has an admin column as a boolean with a similar validation.

validates_uniqueness_of :admin, if: :admin? 

I used shoulda-matchers and rspec to describe the desired outcome.

require 'rails_helper'  RSpec.describe User, type: :model do   let(:user) { build :user }   subject { user }    describe 'validations' do     context 'when admin = true' do       before(:each) { user.admin = true }       it { is_expected.to validate_uniqueness_of(:admin)  }     end   end end 

The spec failed with the following output:

Failures:    1) User validations when admin = true should validate that :admin is case-sensitively unique      Failure/Error: it { is_expected.to validate_uniqueness_of(:admin)  }         User did not properly validate that :admin is case-sensitively unique.          After taking the given User, whose :admin is ‹true›, and saving it as          the existing record, then making a new User and setting its :admin to          ‹true› as well, the matcher expected the new User to be invalid, but          it was valid instead.      # ./spec/models/user_spec.rb:10:in `block (4 levels) in <top (required)>'  Finished in 0.11435 seconds (files took 0.79997 seconds to load) 1 example, 1 failure 

I decided that the code was good and bumped Rails to 4.1.0 exactly.

The spec passed!

bundle update rspec .  Finished in 0.09538 seconds (files took 1.28 seconds to load) 1 example, 0 failures 
Read More

Embeded YouTube video with custom speed (e.g. 3)

Leave a Comment

I have an embeded YouTube video in one page and have a slider with which I can set the player speed.

I am using player.setPlaybackRate(value);

The problem is that I want ranges from 0.5 to 3, but the player API restricts the values only to predefined [0.25, 0.5, 1, 1.25, 1.5, 2].

In YouTube I can easily adjust the speed with document.getElementsByTagName("video")[0].playbackRate = 3 but on the iframe I do not have such access.

Is there any way I can solve the problem?

4 Answers

Answers 1

Where do you see that the player API restricts the values? In the javascript API, you can use setPlaybackRate to set the suggested playback rate, but it says there is no guarentee that what you send will be set. You should use getAvailablePlaybackRates to get the list of playback rates and then choose an appropriate one. You can figure out what rate it was actually set to by listening to the onPlaybackRateChangeevent. If you try to set it to 3 and that is not one of the available rates, it will round towards 1 to the closest rate.

Answers 2

EDIT: This doesn't work anymore.

This is due to the same-origin policy. When an iframe gets accessed by the root origin (your website) it seems to also change the origin of the iframe. So the video can't load from a different origin (youtube.com). See my test on JSFiddle.

I think the fact, that it worked before was a XSS security issue which has been fixed recently. So I can't imagine modifying something in the youtube iframe is even possible anymore. At least not in this way.

Thanks @maxple for pointing out!


Original post:

This should be possible with newer Browsers and the HTML5 Iframe Sandbox Attribute:

With the option you can access the iframe DOM node.

<iframe id="myframe" sandbox="allow-scripts" src="about:blank">    </iframe>  <script>     var frame = document.getElementById("myframe");     var fdoc = frame.contentDocument;      fdoc.getElementsByTagName("video")[0].playbackRate = 3; // or whatever </script> 

See this post for more info.

Answers 3

You can't do the same thing within an iFrame.

What you do within Youtube is to edit the actual video tag, but the only way to do so from another website is through the API provided by Google (due to XSS concerns), and if they've decided to only allow the proposed values, your best shot outside of doing something that may break their Terms of Service, is to contact Google and ask them to allow the third level of speed through the API.

Answers 4

unfortunately, you are trying to edit content of iframe from another domain. none of major browsers allow you to do this via javascript.

i tried and created php file which would get contents of the youtube embed iframe

<?php      $url = $_GET['url'];     $contents = file_get_contents($url);     echo $contents; ?> 

but somehow youtube blocks different origins and it gave me only black screen. as i guessed it is because youtube uses flash player for embed videos (instead of html5 as they do on website).

so i'm sorry but it is impossible.

Read More

laravel how to access column with number name of a table?

Leave a Comment

I make a table with number 22 as the column name. How to access this column?

enter image description here

content:

enter image description here

I've tryed thest

$obj = Tablename::find(1)->first(); $obj->22; $obj->'22';   //'syntax error, unexpected ''22'' $obj->"22"; $obj->`22`; $obj[22]; $arr = $obj->toArray(); var_dump($arr); //  array(15) { ["id"]=> string(2) "25" ["out_trade_no"]=> string(14) "14847080930025" ["22"]=> string(0) "2" $arr[22];       // 'ErrorException' with message 'Undefined offset: 22' $arr['22'];     // 'ErrorException' with message 'Undefined offset: 22' $arr["22"];     // 'ErrorException' with message 'Undefined offset: 22' $arr[`22`];     // 'ErrorException' with message 'Undefined index: ' in $arr[{'22'}];   //  'syntax error, unexpected '{', expecting ']'' in 

none works.

edited as the answer implemented: also get null.

var_dump($orders[0]); var_dump($orders[0]->id); var_dump($orders[0]->{'22'}); $col = '22'; $res = $orders[0]->{$col}; var_dump($res); 

output:

object(Order)#537(21){     [         "connection": protected     ]=>NULL[         "table": protected     ]=>NULL[         "primaryKey": protected     ]=>string(2)"id"[         "perPage": protected     ]=>int(15)[         "incrementing"     ]=>bool(true)[         "timestamps"     ]=>bool(true)[         "attributes": protected     ]=>array(15){         [             "id"         ]=>string(2)"25"[             "out_trade_no"         ]=>string(14)"14847080930025"[             "22"         ]=>string(1)"2"[             "user_id"         ]=>string(2)"49"[             "product_name"         ]=>string(4)"test"[             "amount"         ]=>string(1)"3"[             "fee"         ]=>string(4)"0.03"[             "address_id"         ]=>string(1)"3"[             "trade_status"         ]=>string(13)"TRADE_SUCCESS"[             "express_name"         ]=>string(0)""[             "express_no"         ]=>string(0)""[             "buyer_email"         ]=>string(0)""[             "modify_at"         ]=>string(19)"2017-01-18 10:54:53"[             "created_at"         ]=>string(19)"2017-01-18 10:54:53"[             "updated_at"         ]=>string(19)"2017-01-18 10:55:26"     }[         "original": protected     ]=>array(15){         [             "id"         ]=>string(2)"25"[             "out_trade_no"         ]=>string(14)"14847080930025"[             "22"         ]=>string(1)"2"[             "user_id"         ]=>string(2)"49"[             "product_name"         ]=>string(4)"test"[             "amount"         ]=>string(1)"3"[             "fee"         ]=>string(4)"0.03"[             "address_id"         ]=>string(1)"3"[             "trade_status"         ]=>string(13)"TRADE_SUCCESS"[             "express_name"         ]=>string(0)""[             "express_no"         ]=>string(0)""[             "buyer_email"         ]=>string(0)""[             "modify_at"         ]=>string(19)"2017-01-18 10:54:53"[             "created_at"         ]=>string(19)"2017-01-18 10:54:53"[             "updated_at"         ]=>string(19)"2017-01-18 10:55:26"     }[         "relations": protected     ]=>array(0){      }[         "hidden": protected     ]=>array(0){      }[         "visible": protected     ]=>array(0){      }[         "appends": protected     ]=>array(0){      }[         "fillable": protected     ]=>array(0){      }[         "guarded": protected     ]=>array(1){         [             0         ]=>string(1)"*"     }[         "dates": protected     ]=>array(0){      }[         "touches": protected     ]=>array(0){      }[         "observables": protected     ]=>array(0){      }[         "with": protected     ]=>array(0){      }[         "morphClass": protected     ]=>NULL[         "exists"     ]=>bool(true)[         "softDelete": protected     ]=>bool(false) }string(2)"25"NULLNULL 

Edit: acording to Paras's comment

enter image description here

Edit2: to make question simple and clear:

migration:

<?php  use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration;  class Test extends Migration {      /**      * Run the migrations.      *      * @return void      */     public function up()     {         Schema::create('tests', function($table)         {             $table->increments('id');             $table->integer('22');         });     }      /**      * Reverse the migrations.      *      * @return void      */     public function down()     {         //     }  } 

Model:

<?php class Test extends Eloquent { } 

Controller:

public function show() {     $tests = Test::all();     foreach($tests as $test)     {         Log::info($test->id);         Log::info($test->{'22'});         Log::info($test->{"22"});         Log::info($test->getAttribute("22"));     } } 

data table:

enter image description here

and the log:

[2017-02-25 09:16:48] production.INFO: 1 [] [] [2017-02-25 09:16:48] production.INFO:  [] [] [2017-02-25 09:16:48] production.INFO:  [] [] [2017-02-25 09:16:48] production.INFO:  [] [] [2017-02-25 09:16:48] production.INFO: 2 [] [] [2017-02-25 09:16:48] production.INFO:  [] [] [2017-02-25 09:16:48] production.INFO:  [] [] [2017-02-25 09:16:48] production.INFO:  [] [] 

12 Answers

Answers 1

You can use the following syntax, as found in the variable variables topic in the PHP documentation:

$obj->{'22'}; 

...

Curly braces may also be used, to clearly delimit the property name. They are most useful when accessing values within a property that contains an array, when the property name is made of mulitple parts, or when the property name contains characters that are not otherwise valid (e.g. from json_decode() or SimpleXML).

Answers 2

Try this:

$obj->getAttributeValue("22"); 

Please post the error if it doesn't work

Answers 3

Try this:

$col = '22'; $res = $obj->{$col}; var_dump($res); 

Answers 4

You can use model attribute $maps to give your troublesome column a different name. Try

$maps = ['22' => 'twentytwo'];  $hidden = ['22'];  $appends = ['twentytwo']; 

Then with your model instance

echo $model->twentytwo; 

Answers 5

$arr= Tablename::where('id', 1)->lists('22', 'id')->toArray(); $result = $arr[1];  As 1 is the $id var. I tried it in my localhost and it works 

Answers 6

Possible duplicate of how can I use exists column with laravel model

The same answer applies here; you can use $model->getAttribute('22') to get the value of a model attribute.

Answers 7

Try to use where: Tablename::where('22','=','value')->first();

Answers 8

$table = Tablename::get();  foreach ($table as $value){    echo $value->22 // Getting column 22 from table } 

Answers 9

The question is similar to this:

Hide number field from Eloquent model in Laravel

Presently this is not possible in Laravel as seen in this line of code located in vendor\symfony\var-dumper\Symfony\Component\VarDumper\Cloner\VarCloner.php at line 74.

if ($zval['zval_isref'] = $queue[$i][$k] === $cookie) {    $zval['zval_hash'] = $v instanceof Stub ? spl_object_hash($v) : null; } 

Here is the hack.

if ($zval['zval_isref'] = (isset($queue[$i][$k])) ? ($queue[$i][$k] === $cookie) : false) {    $zval['zval_hash'] = $v instanceof Stub ? spl_object_hash($v) : null; } 

Issue has been discussed here:

https://github.com/laravel/framework/issues/8710

Answers 10

if you always know the name is 22, you can do this.

 $myfield = 22;  dd($obj->$myfield); 

I tested it and it returns the value in the 22 field correctly.

Answers 11

Best way is NOT to use Integer as a fieldname. It is bad praxis. But if you need, you should access the database with raw method:

public function show() {      $test = DB::table('test')         ->select("22 as twentytwo")         ->get();     foreach($tests as $test)     {         Log::info($test->twentytwo);     } } 

Answers 12

Try use pluck()

$plucked = $collection->pluck('22');  $plucked->all(); 
Read More

Reactive Caching of HTTP Service

Leave a Comment

I am using RsJS 5 (5.0.1) to cache in Angular 2. It works well.

The meat of the caching function is:

const observable = Observable.defer(     () => actualFn().do(() => this.console.log('CACHE MISS', cacheKey))   )   .publishReplay(1, this.RECACHE_INTERVAL)   .refCount().take(1)   .do(() => this.console.log('CACHE HIT', cacheKey)); 

The actualFn is the this.http.get('/some/resource').

Like I say, this is working perfectly for me. The cache is returned from the observable for dureation of the RECACHE_INTERVAL. If a request is made after that inverval, the actualFn() will be called.

What I am trying to figure out is when the RECACHE_INTERVAL expires and the actualFn() is called -- how to return the last value. There is a space of time between when the RECACHE_INTERVAL expires and the actualFn() is replayed that the observable doesn't return a value. I would like to get rid of that gap in time and always return the last value.

I could use a side effect and store the last good value call .next(lastValue) while waiting for the HTTP response to return, but this seems naive. I would like to use a "RxJS" way, a pure function solution -- if possible.

3 Answers

Answers 1

Almost any complicated logic quickly goes out of control if you use plain rxjs. I would rather implement custom cache operator from scratch, you can use this gist as an example.

Answers 2

Your example looks exactly the same as an example is SO Documentation on how to make caching with RxJS 5: Caching HTTP responses

If you modify it a little you can simulate the situation that you describe but I don't think it happens as you think:

See this demo: https://jsbin.com/todude/10/edit?js,console

Notice that I'm trying to get cached results at 1200ms when the case is invalidated and then at 1300ms when the previous request is still pending (it takes 200ms). Both results are received as they should.

This happens because when you subscribe and the publishReplay() doesn't contain any valid value it won't emit anything and won't complete immediately (thanks to take(1)) so it needs to subscribe to its source which makes the HTTP requests (this in fact happens in refCount()).

Then the second subscriber won't receive anything as well and will be added to the array of observers in publishReplay(). It won't make another subscription because it's already subscribed to its source (refCount()) and is waiting for response.

So the situation you're describing shouldn't happen I think. Eventually make a demo that demonstrates your problem.

EDIT:

Emitting both invalidated item and fresh items

The following example shows a little different functionality than the linked example. If the cached response is invalidated it'll be emitted anyway and then it receives also the new value. This means the subscriber receives one or two values:

  • 1 value: The cached value
  • 2 values: The invalidated cached value and then new a fresh value that'll be cached from now on.

The code could look like the following:

let counter = 1; const RECACHE_INTERVAL = 1000;  function mockDataFetch() {   return Observable.of(counter++)     .delay(200); }  let source = Observable.defer(() => {   const now = (new Date()).getTime();    return mockDataFetch()     .map(response => {       return {         'timestamp': now,         'response': response,       };     }); });  let updateRequest = source   .publishReplay(1)   .refCount()   .concatMap(value => {     if (value.timestamp + RECACHE_INTERVAL > (new Date()).getTime()) {       return Observable.from([value.response, null]);     } else {       return Observable.of(value.response);     }   })   .takeWhile(value => value);   setTimeout(() => updateRequest.subscribe(val => console.log("Response 0:", val)), 0); setTimeout(() => updateRequest.subscribe(val => console.log("Response 50:", val)), 50); setTimeout(() => updateRequest.subscribe(val => console.log("Response 200:", val)), 200); setTimeout(() => updateRequest.subscribe(val => console.log("Response 1200:", val)), 1200); setTimeout(() => updateRequest.subscribe(val => console.log("Response 1300:", val)), 1300); setTimeout(() => updateRequest.subscribe(val => console.log("Response 1500:", val)), 1500); setTimeout(() => updateRequest.subscribe(val => console.log("Response 3500:", val)), 3500); 

See live demo: https://jsbin.com/ketemi/2/edit?js,console

This prints to console the following output:

Response 0: 1 Response 50: 1 Response 200: 1 Response 1200: 1 Response 1300: 1 Response 1200: 2 Response 1300: 2 Response 1500: 2 Response 3500: 2 Response 3500: 3 

Notice 1200 and 1300 received first the old cached value 1 immediately and then another value with the fresh 2 value.
On the other hand 1500 received only the new value because 2 is already cached and is valid.

The most confusing thing is probably why am I using concatMap().takeWhile(). This is because I need to make sure that the fresh response (not the invalidated) is the last value before sending complete notification and there's probably no operator for that (neither first() nor takeWhile() are applicable for this use-case).

Emitting only the current item without waiting for refresh

Yet another use-case could be when we want to emit only the cached value while not waiting for fresh response from the HTTP request.

let counter = 1; const RECACHE_INTERVAL = 1000;  function mockDataFetch() {   return Observable.of(counter++)     .delay(200); }  let source = Observable.defer(() => {   const now = (new Date()).getTime();    return mockDataFetch()     .map(response => {       return {         'timestamp': now,         'response': response,       };     }); });  let updateRequest = source   .publishReplay(1)   .refCount()   .concatMap((value, i) => {     if (i === 0) {       if (value.timestamp + RECACHE_INTERVAL > (new Date()).getTime()) { // is cached item valid?         return Observable.from([value.response, null]);       } else {         return Observable.of(value.response);       }     }     return Observable.of(null);   })   .takeWhile(value => value);   setTimeout(() => updateRequest.subscribe(val => console.log("Response 0:", val)), 0); setTimeout(() => updateRequest.subscribe(val => console.log("Response 50:", val)), 50); setTimeout(() => updateRequest.subscribe(val => console.log("Response 200:", val)), 200); setTimeout(() => updateRequest.subscribe(val => console.log("Response 1200:", val)), 1200); setTimeout(() => updateRequest.subscribe(val => console.log("Response 1300:", val)), 1300); setTimeout(() => updateRequest.subscribe(val => console.log("Response 1500:", val)), 1500); setTimeout(() => updateRequest.subscribe(val => console.log("Response 3500:", val)), 3500); setTimeout(() => updateRequest.subscribe(val => console.log("Response 3800:", val)), 3800); 

See live demo: https://jsbin.com/kebapu/2/edit?js,console

This example prints to console:

Response 0: 1 Response 50: 1 Response 200: 1 Response 1200: 1 Response 1300: 1 Response 1500: 2 Response 3500: 2 Response 3800: 3 

Notice that both 1200 and 1300 receive value 1 because that's the cached value even though it's invalid now. The first call at 1200 just spawns a new HTTP request without waiting for its response and emits only the cached value. Then at 1500 the fresh value is cached so it's just reemitted. The same applies at 3500 and 3800.

Note, that the subscriber at 1200 will receive the next notification immediately but the complete notification will be sent only after the HTTP request has finished. We need to wait because if we sent complete right after next it'd make the chain to dispose its disposables which should also cancel the HTTP request (which is what we definitely don't want to do).

Answers 3

Updated answer:

If always want to use the previous value while a new request is being made then can put another subject in the chain which keeps the most recent value.

You can then repeat the value so it is possible to tell if it came from the cache or not. The subscriber can then filter out the cached values if they are not interested in those.

// Take values while they pass the predicate, then return one more // i.e also return the first value which returned false const takeWhileInclusive = predicate => src =>   src   .flatMap(v => Observable.from([v, v]))   .takeWhile((v, index) =>      index % 2 === 0 ? true : predicate(v, index)   )   .filter((v, index) => index % 2 !== 1);  // Source observable will still push its values into the subject // even after the subscriber unsubscribes const keepHot = subject => src =>   Observable.create(subscriber => {     src.subscribe(subject);      return subject.subscribe(subscriber);   });  const cachedRequest = request    // Subjects below only store the most recent value    // so make sure most recent is marked as 'fromCache'   .flatMap(v => Observable.from([      {fromCache: false, value: v},      {fromCache: true, value: v}    ]))    // Never complete subject   .concat(Observable.never())    // backup cache while new request is in progress   .let(keepHot(new ReplaySubject(1)))    // main cache with expiry time   .let(keepHot(new ReplaySubject(1, this.RECACHE_INTERVAL)))   .publish()   .refCount()   .let(takeWhileInclusive(v => v.fromCache));    // Cache will be re-filled by request when there is another subscription after RECACHE_INTERVAL   // Subscribers will get the most recent cached value first then an updated value 

https://acutmore.jsbin.com/kekevib/8/edit?js,console

Original answer:

Instead of setting a window size on the replaySubject - you could change the source observable to repeat after a delay.

const observable = Observable.defer(     () => actualFn().do(() => this.console.log('CACHE MISS', cacheKey))   )   .repeatWhen(_ => _.delay(this.RECACHE_INTERVAL))   .publishReplay(1)   .refCount()   .take(1)   .do(() => this.console.log('CACHE HIT', cacheKey)); 

The repeatWhen operator requires RxJs-beta12 or higher https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md#500-beta12-2016-09-09

Read More

Can't use django-compress with Heroku

Leave a Comment

I have a Django 1.9.6 site deployed to Heroku. When DEBUG=False I was getting a server error (500). The logs contained no useful information, so I tried running it with DEBUG=True. Now it works fine. I think the issue may be tied to my scss file processing, which really confuses me and I was struggling with. I recently--among other things--added COMPRESS_OFFLINE = True to my settings files, and commenting that out seems to alleviate the problem (although then my scss files don't work).

Some of my static settings.py. Let me know if you need more--so much of this is a mystery to me. I was trying to follow this as best as I could.

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, "media/")     STATICFILES_FINDERS = (         'django.contrib.staticfiles.finders.FileSystemFinder',         'django.contrib.staticfiles.finders.AppDirectoriesFinder',         # other finders..         'compressor.finders.CompressorFinder',     )      STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'      MEDIA_URL = "/media/"     MEDIA_ROOT = os.path.join(BASE_DIR, "media/") 

in urls.py:

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)  urlpatterns += [     url(r'^media/(?P<path>.*)$', serve, {         'document_root': settings.MEDIA_ROOT     }), ]  urlpatterns += staticfiles_urlpatterns() 

EDIT:

I've gotten logging to work, and I've confirmed that it's a compress error. I'm getting the error message:

Internal Server Error: /  OfflineGenerationError at / You have offline compression enabled but key "171c3b7763dbc51a465d996f7d920cf5" is missing from offline manifest. You may need to run "python manage.py compress". 

which is the same thing I've gotten locally, except running the suggested command solved it. Running heroku run python manage.py compress doesn't have an effect (no errors running it, though)

3 Answers

Answers 1

First off set value for ALLOW_HOSTS, this can't be blank when debug is off.

ALLOWED_HOSTS = ['.mydomain.com', '.2nddomain.com'] 

Because you use compress plugins: SET

COMPRESS_ENABLED = True COMPRESS_OFFLINE = True  # this where the collectstatic and compress result output # point your static alias to here  STATIC_ROOT = os.path.join(BASE_DIR, 'static')  # in your production env: activate ur virtual environment then run the compress statics command python manage.py compress python manage.py collectstatic 

When Debug is off all exceptions is suppressed for security reason, set admin email in the setting file to let django email all un-caught exception

SERVER_EMAIL = 'ur@from-email-address.com' ADMINS = (     ('Exceptions Email', 'destination@email.com'), ) 

Answers 2

Today I tried to share a website with 'PythonAnywhere'. I have encountered the same problem and have fixed the problem with 'Allowed_Host'.

https://docs.djangoproject.com/en/1.10/ref/settings/#allowed-hosts

settings.py

 ALLOWED_HOSTS = ['*'] 

Answers 3

Add this to your settings.py inside the loggers section and it should give you more information (this is what helped point me into solving the same problem).

"django.request": {   "handlers": ["console"],   "level": "ERROR",   "propagate": True } 

For what it's worth, here are my similar settings.py settings:

MEDIA_URL = "http://%s.s3.amazonaws.com/" % (AWS_STORAGE_BUCKET_NAME) BASE_DIR = os.path.dirname(os.path.abspath(__file__)) STATIC_ROOT = 'staticfiles' STATIC_URL = os.getenv("DJANGO_STATIC_HOST", "") + "/static/" if DEBUG:   STATIC_URL = "/static/" STATICFILES_DIRS = (   os.path.join(BASE_DIR, 'static'), ) 

Note: I have no MEDIA_ROOT or STATICFILES_FINDERS and I'm also using Whitenoise with CloudFront for my static file handling

Read More