ID:1886365
 
BYOND Version:508
Operating System:windows server 2012
Web Browser:Chrome 43.0.2357.130
Applies to:Dream Daemon
Status: Open

Issue hasn't been assigned a status value.
It seems if you've got a world.Export() call on an asynchronous event such as client/new() as well as world.Export() elsewhere in the code and they both happen at the same time, whichever one returns first will get read by the first proc to call Export().

## TESTING: Jukebox - Updating playlist from http://ss13.pomf.se/media/index.php?playlist=muzak...
runtime error: Unexpected token: key general
key = "Kurba"
ckey = "kurba"
gender = "male"
joined = "2014-09-24"
online = 1
index:2 .
proc name: die (/json_reader/proc/die)
source file: JSON Reader.dm,220
usr: null
src: /json_reader (/json_reader)
call stack:
/json_reader (/json_reader): die(/json_token/word (/json_token/word))
/json_reader (/json_reader): read value()
Jukebox (/obj/machinery/media/jukebox/dj): retrieve playlist("muzak")
Jukebox (/obj/machinery/media/jukebox/dj): process()
Jukebox (/obj/machinery/media/jukebox/dj): update music()
Radio Transmitter (/obj/machinery/media/transmitter/broadcast/dj): hook media sources()
Radio Transmitter (/obj/machinery/media/transmitter/broadcast/dj): initialize()
/datum/controller/game_control... (/datum/controller/game_controller): setup objects()
/datum/controller/game_control... (/datum/controller/game_controller): setup()
: New()


retrieve_playlist calls export to the media server and returns a json string, in client/New() i've got this.

    var/list/http[] = world.Export("http://www.byond.com/members/[src.key]?format=text")  // Retrieve information from BYOND
var/Joined = 2550-01-01
if(http && http.len && ("CONTENT" in http))
var/String = file2text(http["CONTENT"]) // Convert the HTML file to text
var/JoinPos = findtext(String, "joined")+10 // Parse for the joined date
Joined = copytext(String, JoinPos, JoinPos+10) // Get the date in the YYYY-MM-DD format
You didn't show the code for retrieve_playlist, but is that using the persistent flag? OR, is there any chance exports are being done so frequently on the same URL that two could go out before the first reply comes in?

I found something in the logic that suggests a possible issue here, if one is already open with the right address.
/obj/machinery/media/jukebox/proc/retrieve_playlist(var/playlistid = playlist_id)
playlist_id = playlistid
if(global_playlists["[playlistid]"])
var/list/temp = global_playlists["[playlistid]"]
playlist = temp.Copy()

else
var/url="[config.media_base_url]/index.php?playlist=[playlist_id]"
testing("[src] - Updating playlist from [url]...")

// Media Server 2 requires a secret key in order to tell the jukebox
// where the music files are. It's set in config with MEDIA_SECRET_KEY
// and MUST be the same as the media server's.
//
// Do NOT log this, it's like a password.
if(config.media_secret_key!="")
url += "&key=[config.media_secret_key]"

var/response = world.Export(url)
playlist=list()
if(response)
var/json = file2text(response["CONTENT"])
if("/>" in json)
visible_message("<span class='warning'>\icon[src] \The [src] buzzes, unable to update its playlist.</span>","<em>You hear a buzz.</em>")
stat &= BROKEN
update_icon()
return 0
var/json_reader/reader = new()
reader.tokens = reader.ScanJson(json)
reader.i = 1
var/songdata = reader.read_value()
for(var/list/record in songdata)
playlist += new /datum/song_info(record)
if(playlist.len==0)
visible_message("<span class='warning'>\icon[src] \The [src] buzzes, unable to update its playlist.</span>","<em>You hear a buzz.</em>")
stat &= BROKEN
update_icon()
return 0
visible_message("<span class='notice'>\icon[src] \The [src] beeps, and the menu on its front fills with [playlist.len] items.</span>","<em>You hear a beep.</em>")
else
testing("[src] failed to update playlist: Response null.")
stat &= BROKEN
update_icon()
return 0
global_playlists["[playlistid]"] = playlist.Copy()
if(autoplay)
playing=1
autoplay=0
return 1
Is there a chance either of these URLs is being quickly called twice in a row?
Yes the byond members lookup, thats in client/new() so quite possible its called several times in a row quickly
Hmm, I just realized neither of these actually fits the pattern of the logic error I think I found. HTTP requests are handled a different way. Still looking.